您的位置:首页 > 运维架构 > Apache

apache shiro RememberMe 为false的一个问题解说

2017-04-11 09:56 369 查看
刚刚有一个网友 问我一个问题说他登录的时候 设置了

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 not 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 Amazon.com 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 probably 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>
Update your contact information.
</shiro:authenticated>


就是说 如果是 authc的情况下 是不能和user并存的 而user级别 恰恰就是 RememberMe =true

很多时候 我们遇到问题的时候往往先把自己往错误的地方带 往错误的方向去走

这样才会迷茫 ,我们要先弄懂 原因必须追根溯源
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: