SpringBoot學習:整合shiro(rememberMe記住我功能)


項目下載地址:http://download.csdn.NET/detail/aqsunkai/9805821

首先在shiro配置類中注入rememberMe管理器

/**
  * cookie對象;
  * rememberMeCookie()方法是設置Cookie的生成模版,比如cookie的name,cookie的有效時間等等。
  * @return
 */
@Bean
public SimpleCookie rememberMeCookie(){
      //System.out.println("ShiroConfiguration.rememberMeCookie()");
      //這個參數是cookie的名稱,對應前端的checkbox的name = rememberMe
      SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
      //<!-- 記住我cookie生效時間30天 ,單位秒;-->
      simpleCookie.setMaxAge(259200);
      return simpleCookie;
}

/**
  * cookie管理對象;
  * rememberMeManager()方法是生成rememberMe管理器,而且要將這個rememberMe管理器設置到securityManager中
  * @return
 */
@Bean
public CookieRememberMeManager rememberMeManager(){
      //System.out.println("ShiroConfiguration.rememberMeManager()");
      CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
      cookieRememberMeManager.setCookie(rememberMeCookie());
      //rememberMe cookie加密的密鑰 建議每個項目都不一樣 默認AES算法 密鑰長度(128 256 512 位)
      cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));
      return cookieRememberMeManager;
}

@Bean(name = "securityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(MyShiroRealm realm){
      DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
      //設置realm
      securityManager.setRealm(realm);
      //用戶授權/認證信息Cache, 采用EhCache緩存
      securityManager.setCacheManager(getEhCacheManager());
      //注入記住我管理器
      securityManager.setRememberMeManager(rememberMeManager());
      return securityManager;
}

並且配置記住我或認證通過可以訪問的地址

/**
  * 加載ShiroFilter權限控制規則
 */
private void loadShiroFilterChain(ShiroFilterFactoryBean factoryBean) {
      /**下面這些規則配置最好配置到配置文件中*/
      Map<String, String> filterChainMap = new LinkedHashMap<String, String>();
      //配置記住我或認證通過可以訪問的地址
      filterChainMap.put("/", "user");
      /** authc:該過濾器下的頁面必須驗證后才能訪問,它是Shiro內置的一個攔截器
        * org.apache.shiro.web.filter.authc.FormAuthenticationFilter */
      // anon:它對應的過濾器里面是空的,什么都沒做,可以理解為不攔截
      //authc:所有url都必須認證通過才可以訪問; anon:所有url都都可以匿名訪問
      filterChainMap.put("/permission/userInsert", "anon");
      filterChainMap.put("/error", "anon");
      filterChainMap.put("/tUser/insert","anon");
      filterChainMap.put("/**", "authc");

      factoryBean.setFilterChainDefinitionMap(filterChainMap);
}

login.jsp加上了記住我的input標簽:

<body style="margin-left: 500px">
     <h1 style="margin-left: 30px">登錄頁面----</h1>
     <form action="<%=basePath%>/login" method="post">
         用戶名 : <input type="text" name="email" id="email"/><br>
         密碼: <input type="password" name="pswd" id="pswd"/><br>
         驗證碼:<input type="text" name="gifCode" id="gifCode"/>
         <img alt="驗證碼" src="<%=basePath%>gif/getGifCode"><br>
         <input type="checkbox" name="rememberMe" />記住我<br>
         <input style="margin-left: 100px" type="submit" value="登錄"/><input style="left: 50px" onclick="register()" type="button" value="注冊"/>
     </form>
     <h1 style="color: red">${message }</h1>
</body>

后台的登錄處理方法參數用boolean類型接收,並且在得到身份驗證Token時傳入rememberMe參數

@RequestMapping(value="/login",method=RequestMethod.POST)
public String login(@Valid User user, BindingResult bindingResult,boolean rememberMe,
                        RedirectAttributes redirectAttributes){
        if(bindingResult.hasErrors()){
            return "redirect:login";
        }
        String email = user.getEmail();
        if(StringUtils.isBlank(user.getEmail()) || StringUtils.isBlank(user.getPswd())){
            logger.info("用戶名或密碼為空! ");
            redirectAttributes.addFlashAttribute("message", "用戶名或密碼為空!");
            return "redirect:login";
        }
        //對密碼進行加密后驗證
        UsernamePasswordToken token = new UsernamePasswordToken(user.getEmail(),
                CommonUtils.encrypt(user.getPswd()),rememberMe);
        //獲取當前的Subject
        Subject currentUser = SecurityUtils.getSubject();
        try {
            //在調用了login方法后,SecurityManager會收到AuthenticationToken,並將其發送給已配置的Realm執行必須的認證檢查
            //每個Realm都能在必要時對提交的AuthenticationTokens作出反應
            //所以這一步在調用login(token)方法時,它會走到MyRealm.doGetAuthenticationInfo()方法中,具體驗證方式詳見此方法
            logger.info("對用戶[" + email + "]進行登錄驗證..驗證開始");
            currentUser.login(token);
            logger.info("對用戶[" + email + "]進行登錄驗證..驗證通過");
        }catch(UnknownAccountException uae){
            logger.info("對用戶[" + email + "]進行登錄驗證..驗證未通過,未知賬戶");
            redirectAttributes.addFlashAttribute("message", "未知賬戶");
        }catch(IncorrectCredentialsException ice){
            logger.info("對用戶[" + email + "]進行登錄驗證..驗證未通過,錯誤的憑證");
            redirectAttributes.addFlashAttribute("message", "密碼不正確");
        }catch(LockedAccountException lae){
            logger.info("對用戶[" + email + "]進行登錄驗證..驗證未通過,賬戶已鎖定");
            redirectAttributes.addFlashAttribute("message", "賬戶已鎖定");
        }catch(ExcessiveAttemptsException eae){
            logger.info("對用戶[" + email + "]進行登錄驗證..驗證未通過,錯誤次數大於5次,賬戶已鎖定");
            redirectAttributes.addFlashAttribute("message", "用戶名或密碼錯誤次數大於5次,賬戶已鎖定");
        }catch (DisabledAccountException sae){
            logger.info("對用戶[" + email + "]進行登錄驗證..驗證未通過,帳號已經禁止登錄");
            redirectAttributes.addFlashAttribute("message", "帳號已經禁止登錄");
        }catch(AuthenticationException ae){
            //通過處理Shiro的運行時AuthenticationException就可以控制用戶登錄失敗或密碼錯誤時的情景
            logger.info("對用戶[" + email + "]進行登錄驗證..驗證未通過,堆棧軌跡如下");
            ae.printStackTrace();
            redirectAttributes.addFlashAttribute("message", "用戶名或密碼不正確");
        }
        //驗證是否登錄成功
        if(currentUser.isAuthenticated()){
            logger.info("用戶[" + email + "]登錄認證通過(這里可以進行一些認證通過后的一些系統參數初始化操作)");
            //把當前用戶放入session
            Session session = currentUser.getSession();
            User tUser = permissionService.findByUserEmail(email);
            session.setAttribute("currentUser",tUser);
            return "/welcome";
        }else{
            token.clear();
            return "redirect:login";
        }
}

啟動項目后,第一次輸入http://localhost:8080/boot/后跳轉到login登錄頁面,當登錄成功后,關閉瀏覽器重新打開再輸入地址后,不需要重新登錄,直接跳轉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM