最近在作一個小項目,其中認證這塊使用shiro+SpringMVC+easyUI,由於easyUI在提交數據的時候使用的是ajax的異步提交,因此shiro在處理數據的時候須要重寫FormAuthenticationFilter的相關方法,因此在此記錄下實現的過程,以供大夥參考。
本文只給出核心代碼,完整代碼可去本人github上查看
https://github.com/q279583842q/SRM.gitjava
由於shiro默認的處理驗證的方式是驗證成功直接跳轉到咱們配置的successURL中,若是認證失敗則會跳轉到咱們指定的fail地址,而和easyUI一塊使用的話經過ajax提交,shiro只須要給調用者返回一個驗證的結果就能夠了,因此咱們須要重寫FormAuthenticationFilter中的相關方法,以下:git
/** * 攔截驗證後的請求 * @author 波波烤鴨 * @email dengpbs@163.com * */ public class ShiroLoginFilter extends FormAuthenticationFilter{ private static final Logger log = LoggerFactory.getLogger(FormAuthenticationFilter.class); /** * 表示當訪問拒絕時 * @param request * @param response * @return * @throws Exception */ @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if(this.isLoginRequest(request, response)) { if(this.isLoginSubmission(request, response)) { if(log.isTraceEnabled()) { log.trace("Login submission detected. Attempting to execute login."); } return this.executeLogin(request, response); } else { if(log.isTraceEnabled()) { log.trace("Login page view."); } return true; } } else { if(log.isTraceEnabled()) { log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [" + this.getLoginUrl() + "]"); } this.saveRequestAndRedirectToLogin(request, response); return false; } } /** * * 當登陸成功 * * @param token * @param subject * @param request * @param response * @return * @throws Exception */ @Override protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception { HttpServletResponse httpServletResponse = (HttpServletResponse) response; String requestType = ((HttpServletRequest)request).getHeader("X-Requested-With"); System.out.println("訪問成功...."); if (requestType==null){// 不是ajax請求 System.out.println("訪問成功....1"); issueSuccessRedirect(request, response); } else { System.out.println("訪問成功....2"); httpServletResponse.setCharacterEncoding("UTF-8"); PrintWriter out = httpServletResponse.getWriter(); out.println(JSONObject.toJSON(Resp.success())); out.flush(); out.close(); } return false; } /** * * 當登陸失敗 * * @param token * @param e * @param request * @param response * @return */ @Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { System.out.println("訪問失敗..."); String requestType = ((HttpServletRequest)request).getHeader("X-Requested-With"); System.out.println("訪問失敗..."+requestType); if (requestType==null) {// 不是ajax請求 System.out.println("訪問失敗...1"); setFailureAttribute(request, e); return true; } try { System.out.println("訪問失敗...2"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); String message = e.getClass().getSimpleName(); String info = null; if ("IncorrectCredentialsException".equals(message)) { info = "密碼錯誤"; } else if ("UnknownAccountException".equals(message)) { info = "帳號不存在"; } else if ("LockedAccountException".equals(message)) { info = "帳號被鎖定"; } else { info = "未知錯誤"; } out.println(JSONObject.toJSON(Resp.fail(ErrorCode.SYSTEM_ERROR, info))); out.flush(); out.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } return false; } }
/** * 認證和受權的自定義Realm * * @author 波波烤鴨 * @email dengpbs@163.com * */ public class SecurityRealm extends AuthorizingRealm { @Resource private IUserService userService; /** * 認證的方法 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 獲取提交的帳號 UsernamePasswordToken t = (UsernamePasswordToken) token; // 獲取登陸的帳號 String userName = t.getUsername(); System.out.println("---->" + userName); User user = new User(); user.setUsername(userName); List<User> list = userService.login(userName); if (list == null || list.size() != 1) { // 帳號不存在或者用戶過多都返回null return null; } user = list.get(0); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), "bobo"); return info; } /** * 受權的方法 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { // 省略 。。。 return null; } }
$.ajax({ type: "post" , timeout: 10000 , // 超時時間 10 秒 headers: { 'X-Requested-With':'XMLHttpRequest' } , url: "login.do" , data: $("#ff").serialize() , success: function(data) { if(JSON.parse(data).status==200){ // 表示登陸成功,跳轉到home頁面 location.href="home"; }else{ $.messager.alert('登陸失敗',JSON.parse(data).message); } } });
如此就能夠實現咱們須要的功能了,但願此文對你有所幫助^ _ ^github