java-ee-6 - 注销后 Shiro UnknownSessionException

标签 java-ee-6 shiro

我目前正在 JavaEE6 堆栈中开发 Web 应用程序,并且我已经集成了 Shiro 以确保安全。我认为身份验证和授权现在工作正常,我还有最后一个问题。

当我注销时,遇到UnknownSessionException,这是我的配置和检查代码:

网络.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <!-- Welcome page -->
    <welcome-file-list>
        <welcome-file>home.xhtml</welcome-file>
    </welcome-file-list>

    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>ShiroFilter</filter-name>
        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>ShiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Map these files with JSF -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
</web-app>

shiro.ini

[main]
saltedJdbcRealm = com.czetsuya.commons.web.security.shiro.JdbcRealmImpl

# any object property is automatically configurable in Shiro.ini file
saltedJdbcRealm.jndiDataSourceName = czetsuyaPortal 

# the realm should handle also authorization
saltedJdbcRealm.permissionsLookupEnabled = true

# If not filled, subclasses of JdbcRealm assume "select password from users where username  =  ?"
# first result column is password, second result column is salt 
saltedJdbcRealm.authenticationQuery  =  SELECT password, salt FROM czetsuya_users WHERE username  =  ?

# If not filled, subclasses of JdbcRealm assume "select role_name from user_roles where username  =  ?"
saltedJdbcRealm.userRolesQuery  =  SELECT name FROM czetsuya_roles a INNER JOIN czetsuya_user_roles b ON a.id = b.role_id INNER JOIN czetsuya_users c ON c.id = b.user_id WHERE c.username  =  ?

# If not filled, subclasses of JdbcRealm assume "select permission from roles_permissions where role_name  =  ?"
saltedJdbcRealm.permissionsQuery  =  SELECT action FROM czetsuya_permissions WHERE role  =  ?

# password hashing specification, put something big for hasIterations
sha256Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
sha256Matcher.hashAlgorithmName = SHA-256
sha256Matcher.hashIterations = 1
saltedJdbcRealm.credentialsMatcher = $sha256Matcher
securityManager.realms = saltedJdbcRealm

sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionDAO.activeSessionsCacheName = shiro-activeSessionCache
securityManager.sessionManager.sessionDAO = $sessionDAO

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager

sessionValidationScheduler  =  org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler
# 1,800,000 milliseconds  =  30 mins
sessionValidationScheduler.interval = 1800000
securityManager.sessionManager.sessionValidationScheduler  =  $sessionValidationScheduler

securityManager.sessionManager.sessionIdCookie.domain = com.czetsuya
# 1,800,000 milliseconds = 30 mins
securityManager.sessionManager.globalSessionTimeout = 1800000 

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

czetsuyaFilter = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
czetsuyaFilter.loginUrl = /faces/login.xhtml
czetsuyaFilter.unauthorizedUrl = /faces/login.xhtml
# logout.redirectUrl = /faces/login.xhtml

[urls]
/login.xhtml = czetsuyaFilter
/secure/** = czetsuyaFilter
/api/** = noSessionCreation, czetsuyaFilter
# /logout = logout

我调用注销的部分:

public String logout() {
    Subject subject = SecurityUtils.getSubject();
    if (subject != null) {
        subject.logout();
    }

    return "/home.xhtml?faces-redirect=true";
}

谢谢,
切屋

最佳答案

此配置的问题在于:

securityManager.sessionManager.globalSessionTimeout = 1800000 

应该注释掉。它不适用于 shiro 的 native session 。

或者另一种方法是使用 HttpSession(不是 shiro)。这是配置文件:

[main]
saltedJdbcRealm = com.czetsuya.commons.web.security.shiro.JdbcRealmImpl

# any object property is automatically configurable in Shiro.ini file
saltedJdbcRealm.jndiDataSourceName = dropshipDS 

# the realm should handle also authorization
saltedJdbcRealm.permissionsLookupEnabled = true

# If not filled, subclasses of JdbcRealm assume "select password from users where username  =  ?"
# first result column is password, second result column is salt 
saltedJdbcRealm.authenticationQuery  =  SELECT password, salt FROM crm_users WHERE disabled = false AND username = ?

# If not filled, subclasses of JdbcRealm assume "select role_name from user_roles where username  =  ?"
saltedJdbcRealm.userRolesQuery  =  SELECT name FROM crm_roles a INNER JOIN crm_user_roles b ON a.id = b.role_id INNER JOIN crm_users c ON c.id = b.user_id WHERE c.username = ?

# If not filled, subclasses of JdbcRealm assume "select permission from roles_permissions where role_name  =  ?"
saltedJdbcRealm.permissionsQuery  =  SELECT action FROM crm_permissions WHERE role = ?

# password hashing specification, put something big for hasIterations
sha256Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
sha256Matcher.hashAlgorithmName = SHA-256
sha256Matcher.hashIterations = 1
saltedJdbcRealm.credentialsMatcher = $sha256Matcher
securityManager.realms = $saltedJdbcRealm

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

dsFilter = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
dsFilter.loginUrl = /login.xhtml

roles = com.czetsuya.commons.web.security.shiro.RolesAuthorizationFilter

[urls]
/login.xhtml = dsFilter
/backend/** = dsFilter, roles[backend]
/affiliate/** = dsFilter, roles[affiliate]
/api/** = noSessionCreation, dsFilter
/logout = logout

关于java-ee-6 - 注销后 Shiro UnknownSessionException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13188718/

相关文章:

java - @Resource 未注入(inject)到作为 CDI 托管 bean 的 JAX-WS SE 中

java - 在 Spring MVC 应用程序中使用 CXF 创建 SOAP 客户端时出错

java - 集成测试服务器的数据库填充

grails - Shiro - 如何有效地选择用户有权访问的所有资源?

grails - 用密码登录Apache Shiro Grails中的哈希

java - 在 JBoss 社区 AS 7 中部署简单的 Jax-RS 示例

jakarta-ee - 在 ubuntu 中为 glassfish 服务器设置 jdk 位置

Java (maven) 将 SSL 与 Shiro 结合使用 - Tomcat 7 的 https 端口插件无法正常工作

java - 如何将 Apache Shiro 与 AngularJS 集成

java - Apache shiro 和 JSESSIONID