The Shiro sessions are stored in SessionDAO
with sessionId
as keys. Without extra effort you cannot access a session by a principal (user name). However, you could extend DefaultSecurityManager
and check all active sessions by SessionDAO.getActiveSessions
.
The following codes could be a simple example (suppose you are not using 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);
}
}