日期:2014-05-16  浏览次数:20875 次

apache shiro RememberMe 为false的一个问题解说
刚刚有一个网友 问我一个问题说他登录的时候 设置了
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();
    }


这样应该很清楚原因了 !


他的返回有三个条件 合并起来的 第一个和第二个都是一个意思 就是 该用户信息不为空,
第三个条件代表的意思是 当前用户是通过认证的!

因为