shiro有几种状态,其中包括guest,user,authenticated。guest就是游客,authenticated就是认证后的用户,而user是介于两者之前。user并不代表用户已经成功认证,当用户上次登录时选择rememberMe,下次用户再访问时就是user状态。登录时选择rememberMe,shiro会通过一种加密方式将principal(我们理解为用户名)加密保存到cookie中。shiro可以通过这个cookie解密得到principal。所以当状态为user时,虽然并不代表用户已经通过认证,但我们却可以通过Subject拿到用户名。先贴出代码:
1 | public void autoLogin(HttpServletRequest request, HttpServletResponse response) { |
ShiroAuthorizationHelper在文章我的shiro之旅: 九 shiro 清理缓存的权限信息有介绍。我们来看看DelegatingSubject类的isRemembered()方法的实现。
1 | public boolean isRemembered() { |
当能拿到principals和用户没认证的时候,这个方法才返回true,principals可以通过cookie解密得到。如果用户是认证状态的,这个方法将返回false。
如此看来,shiro的自动登录实现还是比较简单。
securityManager有个rememberMeManager,用来管理rememberMe的,默认情况下,这个cookie会保存一年时间,我们可以看一下RememberMeManager接口的实现类org.apache.shiro.web.mgt.CookieRememberMeManager的源码:
1 | public class CookieRememberMeManager extends AbstractRememberMeManager { |
从构造器中看到cookie.setMaxAge(Cookie.ONE_YEAR);设置cookie的有效时间为一年。也许,这对我们来说会有点长,我们可以更改这些设置。配置如下:
1 | <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> |
当然,我们也可以实现自己的rememberMeManager。