首先在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; }
而且配置記住我或認證經過能夠訪問的地址web
/** * 加載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參數apache
@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登陸頁面,當登陸成功後,關閉瀏覽器從新打開再輸入地址後,不須要從新登陸,直接跳轉。瀏覽器