UsernamePasswordToken token = new UsernamePasswordToken(
currUser.getAccount(), currUser.getPwd());
token.setRememberMe(true);
然后 在登录方法里看到 token 对象里的isRememberMe()方法返回的也是true
为什么到其他action方法里 返回SecurityUtils.getSubject().isRemembered()是false?
起初我也很奇怪 难道他们是两个不同的 调用?
带着这个疑问我查看了 shiro的源码
我首先看了 登录方法里的set方法
实在UsernamePasswordToken.class类里的
/** * Returns <tt>true</tt> if the submitting user wishes their identity (principal(s)) to be remembered * across sessions, <tt>false</tt> otherwise. Unless overridden, this value is <tt>false</tt> by default. * * @return <tt>true</tt> if the submitting user wishes their identity (principal(s)) to be remembered * across sessions, <tt>false</tt> otherwise (<tt>false</tt> by default). * @since 0.9 */ public boolean isRememberMe() { return rememberMe; } /** * Sets if the submitting user wishes their identity (pricipal(s)) to be remembered across sessions. Unless * overridden, the default value is <tt>false</tt>, indicating [i]not[/i] to be remembered across sessions. * * @param rememberMe value inidicating if the user wishes their identity (principal(s)) to be remembered across * sessions. * @since 0.9 */ public void setRememberMe(boolean rememberMe) { this.rememberMe = rememberMe; }
没看出什么
然后我进 boolean re=SecurityUtils.getSubject().isRemembered();
isRemembered();这个方法里看了下
发现是在Subject.class里面的
* {@link #getPrincipals() principals}, such as customized views, it should never perform highly-sensitive * operations until the user has legitimately verified their identity by executing a successful authentication * attempt. * <p/> * We see this paradigm all over the web, and we will use [url=http://www.amazon.com]Amazon.com[/url] as an * example: * <p/> * When you visit Amazon.com and perform a login and ask it to 'remember me', it will set a cookie with your * identity. If you don't log out and your session expires, and you come back, say the next day, Amazon still knows * who you [i]probably[/i] are: you still see all of your book and movie recommendations and similar user-specific * features since these are based on your (remembered) user id. * <p/> * BUT, if you try to do something sensitive, such as access your account's billing data, Amazon forces you * to do an actual log-in, requiring your username and password. * <p/> * This is because although amazon.com assumed your identity from 'remember me', it recognized that you were not * actually authenticated. The only way to really guarantee you are who you say you are, and therefore allow you * access to sensitive account data, is to force you to perform an actual successful authentication. You can * check this guarantee via the {@link #isAuthenticated() isAuthenticated()} method and not via this method. * * @return {@code true} if this {@code Subject}'s identity (aka {@link #getPrincipals() principals}) is * remembered from a successful authentication during a previous session, {@code false} otherwise. * @since 1.0 */ boolean isRemembered();
点进去看实现方法是这样写的:
public boolean isRemembered() { PrincipalCollection principals = getPrincipals(); return principals != null && !principals.isEmpty() && !isAuthenticated(); }
这样应该很清楚原因了 !
他的返回有三个条件 合并起来的 第一个和第二个都是一个意思 就是 该用户信息不为空,
第三个条件代表的意思是 当前用户是通过认证的!
因为我是刚刚登录不久 肯定这个条件是为isAuthenticated();肯定是true
但是他前面加了一个感叹号("!") 那合起来就是false了 三个条件 合起来
true&&true&&false
结果当然就是false
它的意思 就是 因为该用户是 认证通过的所以是 false
我们可以回过头看看这两个标签的解释
user标签 认证通过或已记住的用户 <shiro:user> Welcome back John! Not John? Click <a href="login.jsp">here<a> to login. </shiro:user> authenticated标签 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。 <shiro:authenticated> [url=updateAccount.jsp]Update your contact information[/url]. </shiro:authenticated>
就是说 如果是 authc的情况下 是不能和user并存的 而user级别 恰恰就是 RememberMe =true
很多时候 我们遇到问题的时候往往先把自己往错误的地方带 往错误的方向去走
这样才会迷茫 ,我们要先弄懂 原因必须追根溯源