SpringBoot+shiro 实现rememberMe

ShiroConfig.java

@Configuration
public class ShiroConfig {

    //注入自定义的realm,告诉shiro如何获取用户信息来做登录或权限控制
    @Bean
    public Realm realm() {
        return new MyRealm();
    }

    public SimpleCookie rememberMeCookie() {
        // 设置cookie名称,对应login.html页面的
        SimpleCookie cookie = new SimpleCookie("rememberMe");
        // 设置cookie的过期时间,单位为秒,这里为一天
        cookie.setMaxAge(86400);
        return cookie;
    }

    /**
     * cookie管理对象
     * @return
     */
    public CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        // rememberMe cookie加密的密钥
        cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
        return cookieRememberMeManager;
    }

    @Bean
    public SessionsSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //将自定义的realm交给SecurityManager管理
        securityManager.setRealm(realm());
        // 使用记住我
        securityManager.setRememberMeManager(rememberMeManager());
        return securityManager;
    }


    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        /**
         * setUsePrefix(false)用于解决一个奇怪的bug。在引入spring aop的情况下。
         * 在@Controller注解的类的方法中加入@RequiresRole注解,会导致该方法无法映射请求,导致返回404。
         * 加入这项配置能解决这个bug
         */
        creator.setUsePrefix(true);
        return creator;
    }

    /**
     * 这里统一做鉴权,即判断哪些请求路径需要用户登录,哪些请求路径不需要用户登录。
     * 这里只做鉴权,不做权限控制,因为权限用注解来做。
     * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition();
        //哪些请求可以匿名访问
        chain.addPathDefinition("/login", "anon");
        chain.addPathDefinition("/userLogin", "anon");
        chain.addPathDefinition("/static/**", "anon");

        //除了以上的请求外,其它请求都需要登录
        chain.addPathDefinition("/**", "user");
        return chain;
    }


}

Controller

@RequestMapping("userLogin")
    @ResponseBody
    public Result userLogin(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam(value = "rememberme",required = false) String rememberme,HttpSession session){
        Subject currentUser = SecurityUtils.getSubject();
        try {
            String depassword = null;//解密密码
            try {
                depassword = AesUtil.aesDecrypt(password); //解密web传值的密码
            } catch (Exception e) {
                e.printStackTrace();
            }
            UsernamePasswordToken token = new UsernamePasswordToken(username, depassword);
            rememberme = rememberme == null ? "false" : rememberme;   //null=>false
            token.setRememberMe(Boolean.parseBoolean(rememberme));
            //登录
            currentUser.login(token);
            //从session取出用户信息
            User user = (User) currentUser.getPrincipal();
            session.setAttribute("user",user);
            if (user==null) throw new AuthenticationException();
            //返回登录用户的信息给前台,含用户的所有角色和权限
            return ResultGenerator.genSuccessResult();
        } catch ( UnknownAccountException uae ) {
            return ResultGenerator.genFailResult("登录失败,用户或密码错误!");
        } catch ( IncorrectCredentialsException ice ) {
            return ResultGenerator.genFailResult("登录失败,用户或密码错误!");
        } catch ( AuthenticationException ae ) {
            return ResultGenerator.genServiceErrorResult();
        }
    }

注意,User类需要实现

Serializable

增加属性

private static final long serialVersionUID = 1L;

你可能感兴趣的:(SpringBoot)