Shiro实现rememberMe功能

  • Post author:
  • Post category:其他




一、介绍

Shiro提供了记住我(RememberMe) 的功能,比如访问一些网站时,关闭了浏览器,下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问。

基本流程

  1. 首先在登录页面选中RememberMe然后登录成功;如果是浏览器登录,一般会把RememberMe的Cookie写到客户端并保存下来;
  2. 关闭浏览器再重新打开;会发现浏览器还是记住你的;
  3. 访问一般的网页服务器端,仍然知道你是谁,且能正常访问;
  4. 但是,如果我们访问电商平台时,如果要查看我的订单或进行支付时,此时还是需要再进行身份认证的,以确保当前用户还是你。



二、实现



2.1、沿用博客“登录认证前端”的项目



2.2、在ShiroConfig中配置cookie属性

    //cookie属性设置
    public SimpleCookie rememberMeCookie(){
        SimpleCookie cookie = new SimpleCookie("rememberMe");
        //设置跨域
        //cookie.setDomain(domain);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(30*24*60*60);
        return cookie;
    }



2.3、在ShiroConfig中创建Shiro的cookie管理对象

    //创建Shiro的cookie管理对象
    public CookieRememberMeManager rememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        cookieRememberMeManager.setCipherKey("1234567890987654".getBytes());
        return cookieRememberMeManager;
    }



2.4、在ShiroConfig内置过滤器中添加存在用户的过滤器

   @Bean
    public DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
        //设置不认证可以访问的资源
        definition.addPathDefinition("/myController/userLogin","anon");
        definition.addPathDefinition("/myController/login","anon");
        //设置需要进行登录认证的拦截范围
        definition.addPathDefinition("/**","authc");
        //添加存在用户的过滤器(rememberMe)
        definition.addPathDefinition("/**","user");
        return definition;
    }



2.5、设置rememberMe

    //配置SecurityManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(){
        //1.创建defaultWebSecurityManager对象
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //2.创建加密对象,设置相关属性
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //2.1.采用md5加密
        matcher.setHashAlgorithmName("md5");
        //2.2.迭代加密的次数
        matcher.setHashIterations(3);
        //3.将加密对象存储到myRealm中
        myRealm.setCredentialsMatcher(matcher);
        //4.将myRealm存入defaultWebSecurityManager对象
        defaultWebSecurityManager.setRealm(myRealm);
        //4.5、设置rememberMe
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager());
        //5.返回
        return defaultWebSecurityManager;
    }



2.6、在login.html添加rememberMe

在这里插入图片描述



2.7、修改MyController类,如下

package com.massimo.shiro.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("myController")
public class MyController {

    @GetMapping("userLogin")
    public String userLogin(String name, String pwd, HttpSession session, @RequestParam(defaultValue = "false") boolean rememberMe){
        //1.获取subject对象
        Subject subject = SecurityUtils.getSubject();
        //2.封装请求数据到token
        AuthenticationToken token = new UsernamePasswordToken(name,pwd,rememberMe);
        //3.调用login方法进行登录验证
        try {
            subject.login(token);
            session.setAttribute("user",token.getPrincipal().toString());
            return "main";
        } catch (AuthenticationException e) {
            e.printStackTrace();
            System.out.println("登陆失败");
            return "登录失败";
        }
    }

    //登录认证验证rememberMe
    @GetMapping("userLoginRm")
    public String userLogin(HttpSession session){
        session.setAttribute("user","rememberMe");
        return "main";
    }

//    //跳转登录页面
    @GetMapping("login")
    public String login(){
        return "login";
    }
}



版权声明:本文为Massimo__JAVA原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。