使用 Apache Shiro 和 Tomcat 进行单点登录

Single Sign on with Apache Shiro and Tomcat

我有两个独立的 Maven 模块:一个是休息应用程序,另一个是 Web 应用程序。

他们运行在同一个tomcat7台服务器上,部署为不同的war,使用Shiro进行认证授权。

由于 Web 应用程序需要对其余服务进行 ajax 调用,我认为将这个 SSO 东西添加到两个应用程序会很好。因此,按照 this answer 的建议,我对模块进行了必要的更改,希望这是一项简单的任务,但对我来说并非如此。我可以分别在每个应用程序中进行身份验证,但无法让它们共享会话信息。每次我登录网络应用程序并尝试访问休息服务时,我都会被重定向到休息服务登录页面,反之亦然。

这是网络应用的 shiro.ini 内容:

[main]

credentialsMatcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName = SHA-256

dataSource = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
dataSource.user = ****
dataSource.password = ****
dataSource.port = ****
dataSource.url = jdbc:mysql://localhost:****/****
dataSource.databaseName = ****

jdbcRealm = com.camacua.shiro.realm.SaltAwareJdbcRealm
jdbcRealm.credentialsMatcher = $credentialsMatcher
jdbcRealm.dataSource = $dataSource
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.saltStyle = COLUMN
jdbcRealm.saltedAuthenticationQuery = select password, password_salt, userId from AccountInfo where username = ?
jdbcRealm.userRolesQuery = select role_name from AccountInfo_Role where accountInfo_username = ?
jdbcRealm.permissionsQuery = select permission_name from Role_Permission where role_name = ?
securityManager.realm = $jdbcRealm

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionManager.sessionDAO = $sessionDAO
cookie = org.apache.shiro.web.servlet.SimpleCookie
cookie.name = SSOcookie
cookie.path = /
cookie.domain = localhost
sessionManager.sessionIdCookie = $cookie
securityManager.sessionManager = $sessionManager

cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager.cacheManagerConfigFile = classpath:ehcache.xml
securityManager.cacheManager = $cacheManager

securityManager.sessionMode = native

#Para testing:
ssl.enabled=false

shiro.loginUrl = /login.jsp

[urls]
/css/**=anon
/img/**=anon
/logout = logout
/** = ssl,authc

其余应用程序的 shiro.ini 文件:

[main]
credentialsMatcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName = SHA-256

dataSource = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
dataSource.user = ****
dataSource.password = ****
dataSource.port = ****
dataSource.url = jdbc:mysql://localhost:****/****
dataSource.databaseName = ****

jdbcRealm = com.camacua.shiro.realm.SaltAwareJdbcRealm
jdbcRealm.credentialsMatcher = $credentialsMatcher
jdbcRealm.dataSource = $dataSource
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.saltStyle = COLUMN
jdbcRealm.saltedAuthenticationQuery = select password, password_salt, userId from AccountInfo where username = ?
jdbcRealm.userRolesQuery = select role_name from AccountInfo_Role where accountInfo_username = ?
jdbcRealm.permissionsQuery = select permission_name from Role_Permission where role_name = ?
securityManager.realm = $jdbcRealm

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionManager.sessionDAO = $sessionDAO
cookie = org.apache.shiro.web.servlet.SimpleCookie
cookie.name = SSOcookie
cookie.path = /
cookie.domain = localhost
sessionManager.sessionIdCookie = $cookie
securityManager.sessionManager = $sessionManager

cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager.cacheManagerConfigFile = classpath:ehcache.xml
securityManager.cacheManager = $cacheManager

securityManager.sessionMode = native

#ssl.enabled=false

authc.loginUrl = /login

[urls]
/test/** = anon
/** = authc

ehcache.xml 文件完全包含 stormpath 站点在两个项目中建议的内容:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
         monitoring="autodetect" dynamicConfig="true">

    <diskStore path="java.io.tmpdir" />

    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="peerDiscovery=automatic,
                        multicastGroupAddress=230.0.0.1,
                        multicastGroupPort=4446, timeToLive=1"
            propertySeparator="," />

    <cacheManagerPeerListenerFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" />

    <cache name="shiro-activeSessionCache" maxElementsInMemory="600"
           eternal="true" overflowToDisk="true" memoryStoreEvictionPolicy="LFU">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
    </cache>

    <defaultCache maxElementsInMemory="100" eternal="true"
                  overflowToDisk="true" memoryStoreEvictionPolicy="LFU">
    </defaultCache>
</ehcache>

如您所见,我使用的是自定义领域,但我很确定它工作正常,因为身份验证部分根本没有给我带来任何问题。关于我做错了什么的任何建议?提前致谢。

更新: 我刚刚复制了 web 项目并重命名了它。 运行两个web twin应用效果一样。

问题与我创建的 jsp 个页面有关。我在会话范围内声明了变量。这不知何故覆盖了会话 cookie,并丢失了会话 ID。