如何检查用户是否已使用Apache Shiro登录?

时间:2014-01-13 15:49:29

标签: java apache shiro

问题很简单。我想限制来自不同机器/浏览器的相同登录的用户访问:只能进行一次实时用户会话。

Apache shiro库用于用户身份验证和管理。

当然这可以使用简单的同步地图等来完成。但问题是:Apache Shiro有特殊机制吗?

此问题的另一个变体:如何使用apache shiro显示使用系统登录系统的所有主题列表?

UPD:

澄清我的问题。我的愿望是拥有这样的代码(我知道,没有这样的类异常,但想法必须更干净):

Subject currentUser = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(login, password);
try {
    currentUser.login(token);
} catch (AlreadyAuthenticatedException aae) {
    errorMsg = "You should logoff on another machine!";
}

1 个答案:

答案 0 :(得分:1)

Shiro会话存储在SessionDAO中,sessionId作为键。无需额外工作,您无法通过主体(用户名)访问会话。但是,您可以扩展DefaultSecurityManager并按SessionDAO.getActiveSessions检查所有活动会话。 以下代码可能是一个简单的示例(假设您没有使用WebSubject):

public class UniquePrincipalSecurityManager extends org.apache.shiro.mgt.DefaultSecurityManager {

    @Override
    public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {

        String loginPrincipal = (String) token.getPrincipal();
        DefaultSessionManager sm = (DefaultSessionManager) getSessionManager();
        for (Session session : sm.getSessionDAO().getActiveSessions()) {
            SimplePrincipalCollection p = (SimplePrincipalCollection) session
                    .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
            if (p != null && loginPrincipal.equals(p.getPrimaryPrincipal())) {
                throw new AlreadyAuthenticatedException();
            }

        }
        return super.login(subject, token);
    }

}