zoukankan      html  css  js  c++  java
  • 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登录页面,当登录成功后,关闭浏览器重新打开再输入地址后,不需要重新登录,直接跳转。

  • 相关阅读:
    挺喜欢的一幅摄影作品,不知道作者 不知道出处...
    使用触发器来监控表的使用情况
    SQL Server 针对表的只读权限分配
    tnslsnr.exe进程占用大量内存的解决.
    记录一次MYSQL的备份(浅尝辄止型)
    记录temp被撑爆的一次SQL tuning
    Bug 5880921 V$SYSMETRIC_HISTORY 的时间错乱
    sqlite3学习记录
    指针 数组指针 指针数组 函数指针等说明。
    c/c++ 运算符 优先级 结合性 记录
  • 原文地址:https://www.cnblogs.com/tongxuping/p/7210146.html
Copyright © 2011-2022 走看看