SpringBoot学习:整合shiro(rememberMe记住我功能)

在shiro配置类中注入rememberMe管理器:

 1 /**  
 2   * cookie对象;  
 3   * rememberMeCookie()方法是设置Cookie的生成模版,比如cookie的name,cookie的有效时间等等。  
 4   * @return  
 5  */  
 6 @Bean  
 7 public SimpleCookie rememberMeCookie(){  
 8       //System.out.println("ShiroConfiguration.rememberMeCookie()");  
 9       //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe  
10       SimpleCookie simpleCookie = new SimpleCookie("rememberMe");  
11       //<!-- 记住我cookie生效时间30天 ,单位秒;-->  
12       simpleCookie.setMaxAge(259200);  
13       return simpleCookie;  
14 }  
15   
16 /**  
17   * cookie管理对象;  
18   * rememberMeManager()方法是生成rememberMe管理器,而且要将这个rememberMe管理器设置到securityManager中  
19   * @return  
20  */  
21 @Bean  
22 public CookieRememberMeManager rememberMeManager(){  
23       //System.out.println("ShiroConfiguration.rememberMeManager()");  
24       CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();  
25       cookieRememberMeManager.setCookie(rememberMeCookie());  
26       //rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)  
27       cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));  
28       return cookieRememberMeManager;  
29 }  
30   
31 @Bean(name = "securityManager")  
32 public DefaultWebSecurityManager defaultWebSecurityManager(MyShiroRealm realm){  
33       DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();  
34       //设置realm  
35       securityManager.setRealm(realm);  
36       //用户授权/认证信息Cache, 采用EhCache缓存  
37       securityManager.setCacheManager(getEhCacheManager());  
38       //注入记住我管理器  
39       securityManager.setRememberMeManager(rememberMeManager());  
40       return securityManager;  
41 }

配置记住我或认证通过可以访问的地址:

 1 /**  
 2   * 加载ShiroFilter权限控制规则  
 3  */  
 4 private void loadShiroFilterChain(ShiroFilterFactoryBean factoryBean) {  
 5       /**下面这些规则配置最好配置到配置文件中*/  
 6       Map<String, String> filterChainMap = new LinkedHashMap<String, String>();  
 7       //配置记住我或认证通过可以访问的地址  
 8       filterChainMap.put("/", "user");  
 9       /** authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器  
10         * org.apache.shiro.web.filter.authc.FormAuthenticationFilter */  
11       // anon:它对应的过滤器里面是空的,什么都没做,可以理解为不拦截  
12       //authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问  
13       filterChainMap.put("/permission/userInsert", "anon");  
14       filterChainMap.put("/error", "anon");  
15       filterChainMap.put("/tUser/insert","anon");  
16       filterChainMap.put("/**", "authc");  
17   
18       factoryBean.setFilterChainDefinitionMap(filterChainMap);  
19 }  

登录jsp,并设置记住我的选项:

 1 <body style="margin-left: 500px">  
 2      <h1 style="margin-left: 30px">登录页面----</h1>  
 3      <form action="<%=basePath%>/login" method="post">  
 4          用户名 : <input type="text" name="email" id="email"/><br>  
 5          密码: <input type="password" name="pswd" id="pswd"/><br>  
 6          验证码:<input type="text" name="gifCode" id="gifCode"/>  
 7          <img alt="验证码" src="<%=basePath%>gif/getGifCode"><br>  
 8          <input type="checkbox" name="rememberMe" />记住我<br>  
 9          <input style="margin-left: 100px" type="submit" value="登录"/><input style="left: 50px" onclick="register()" type="button" value="注册"/>  
10      </form>  
11      <h1 style="color: red">${message }</h1>  
12 </body>  

后台的登录处理方法参数用boolean类型接收,并且在得到身份验证Token时传入rememberMe参数:

 1 @RequestMapping(value="/login",method=RequestMethod.POST)  
 2 public String login(@Valid User user, BindingResult bindingResult,boolean rememberMe,  
 3                         RedirectAttributes redirectAttributes){  
 4         if(bindingResult.hasErrors()){  
 5             return "redirect:login";  
 6         }  
 7         String email = user.getEmail();  
 8         if(StringUtils.isBlank(user.getEmail()) || StringUtils.isBlank(user.getPswd())){  
 9             logger.info("用户名或密码为空! ");  
10             redirectAttributes.addFlashAttribute("message", "用户名或密码为空!");  
11             return "redirect:login";  
12         }  
13         //对密码进行加密后验证  
14         UsernamePasswordToken token = new UsernamePasswordToken(user.getEmail(),  
15                 CommonUtils.encrypt(user.getPswd()),rememberMe);  
16         //获取当前的Subject  
17         Subject currentUser = SecurityUtils.getSubject();  
18         try {  
19             //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查  
20             //每个Realm都能在必要时对提交的AuthenticationTokens作出反应  
21             //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法  
22             logger.info("对用户[" + email + "]进行登录验证..验证开始");  
23             currentUser.login(token);  
24             logger.info("对用户[" + email + "]进行登录验证..验证通过");  
25         }catch(UnknownAccountException uae){  
26             logger.info("对用户[" + email + "]进行登录验证..验证未通过,未知账户");  
27             redirectAttributes.addFlashAttribute("message", "未知账户");  
28         }catch(IncorrectCredentialsException ice){  
29             logger.info("对用户[" + email + "]进行登录验证..验证未通过,错误的凭证");  
30             redirectAttributes.addFlashAttribute("message", "密码不正确");  
31         }catch(LockedAccountException lae){  
32             logger.info("对用户[" + email + "]进行登录验证..验证未通过,账户已锁定");  
33             redirectAttributes.addFlashAttribute("message", "账户已锁定");  
34         }catch(ExcessiveAttemptsException eae){  
35             logger.info("对用户[" + email + "]进行登录验证..验证未通过,错误次数大于5次,账户已锁定");  
36             redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数大于5次,账户已锁定");  
37         }catch (DisabledAccountException sae){  
38             logger.info("对用户[" + email + "]进行登录验证..验证未通过,帐号已经禁止登录");  
39             redirectAttributes.addFlashAttribute("message", "帐号已经禁止登录");  
40         }catch(AuthenticationException ae){  
41             //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景  
42             logger.info("对用户[" + email + "]进行登录验证..验证未通过,堆栈轨迹如下");  
43             ae.printStackTrace();  
44             redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");  
45         }  
46         //验证是否登录成功  
47         if(currentUser.isAuthenticated()){  
48             logger.info("用户[" + email + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");  
49             //把当前用户放入session  
50             Session session = currentUser.getSession();  
51             User tUser = permissionService.findByUserEmail(email);  
52             session.setAttribute("currentUser",tUser);  
53             return "/welcome";  
54         }else{  
55             token.clear();  
56             return "redirect:login";  
57         }  
58 }  

  启动项目后,第一次进入页面跳转到login登录页面,当登录成功后,关闭浏览器重新打开再输入地址后,不需要重新登录,直接跳转。

原文地址:https://www.cnblogs.com/tongxuping/p/7210146.html