Search code examples
sessionlogoutshiro

how to close shiro session


I met an error when hardcode try to logout with shiro. user do login and logout not through web login/logout url, but backend link.

when login, it works.

Subject currentUser = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(request.getParameter("username"), request.getParameter("password"));
        token.setRememberMe(true);
        try {
            currentUser.login(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }

but when i try to logout, with error:

public void userLogout(String sessionId){
    SecurityManager securityManager = SecurityUtils.getSecurityManager();
    Subject.Builder builder = new Subject.Builder(securityManager);
    builder.sessionId(sessionId);
    Subject subject = builder.buildSubject();
    if (null != subject) {
        try {
            subject.logout();
        } catch (SessionException e) {
            // TODO: handle exception
        }
    }
}

but met error [org.apache.shiro.session.UnknownSessionException: There is no session with id , then how to manually colse a shiro session?


Solution

  • You shouldn't try to recreate the session and then operate it, you should get the session via the security manager, using the thread the user was logged into, like so:

    SecurityUtils.getSubject().logout();
    

    If you somehow want to call logout from a different thread, you can use the SessionDAO interface, but you need to do extra configuration to have shiro use a SessionDAO as described here:

    http://shiro.apache.org/session-management.html#SessionManagement-SessionStorage

    When you have configured it correctly you can do stuff like:

        DefaultSecurityManager securityManager = (DefaultSecurityManager) SecurityUtils.getSecurityManager();
        DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();
        Collection<Session> activeSessions = sessionManager.getSessionDAO().getActiveSessions();
        for (Session session: activeSessions){
            if (sessionId.equals(session.getId()){
                session.stop();
            }
        }