剛剛有一個網友 問我一個問題說他登陸的時候 設置了
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 不少時候 咱們遇到問題的時候每每先把本身往錯誤的地方帶 往錯誤的方向去走 這樣纔會迷茫 ,咱們要先弄懂 緣由必須追根溯源