I'm using apache shiro with rememberMe active. The rememberMe token is saved in cookie. I want to force all devices login using the same username to logout after password reset. I managed to invalidate all sessions of the same user, however the rememberMe token saved in each device always creating a new valid session. Thus the other devices still can access restricted data.
This is how I invalidate the sessions:
DefaultSecurityManager securityManager = (DefaultSecurityManager) SecurityUtils.getSecurityManager();
DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();
Collection<Session> activeSessions = sessionManager.getSessionDAO().getActiveSessions();
for (Session session : activeSessions) {
Subject subject = new Subject.Builder().sessionId(session.getId()).buildSubject();
if (theUsernameChangingThePassword.equals(subject.getPrincipal().toString())) {
subject.logout();
}
}
Is there a way to invalidate rememberMe token on username/principal basis? How do you guys handle this?
Using the rememberMe feature
To force a logout on all devices after a password reset with the rememberMe feature active in Apache Shiro, you can do the following:
In your Apache Shiro configuration, set the rememberMeCookie.maxAge property to a negative value. This will cause the rememberMe cookie to expire immediately, effectively logging out the user on all devices.
After the password reset is complete, set the rememberMeCookie.maxAge property back to a positive value (e.g. 604800 seconds, which is one week). This will enable the rememberMe feature again, but the user will be required to login again on all devices.
For example, your Apache Shiro configuration might look something like this:
Then, after the password reset is complete, you could set the rememberMeCookie.maxAge property back to a positive value like this:
This will cause the rememberMe cookie to expire immediately, logging out the user on all devices, and then enable the rememberMe feature again with a one-week expiration time. This will ensure that the user is required to login again on all devices after the password reset.
Note that this approach is only effective if the user has the rememberMe feature enabled on all devices. If the user has the rememberMe feature enabled on only some devices, those devices will remain logged in after the password reset, and the user will need to manually log out on those devices. Additionally, this approach will not work if the user has disabled cookies in their browser, as the rememberMe cookie will not be set and will not be able to be expired.
using a session store
When you are using a session store, you can just purge all sessions there. Consider this section (session storage) from the documentation: https://shiro.apache.org/session-management.html#SessionManagement-SessionManager-Storage
So, if you defined your own session storage (e.g. a database, a hazelcast cluster, etc.), you can just empty the table there.
when using JWT
... you better have an expiration date set. Or just switch the secret keys, so users are forced to re-login.
when not using any of those features
The default session manager will use an in-memory implementation and does not use clustering. Just restart your application
when not using sessions at all
... no logout is required, as users will need to authenticate on every request.