Shiro+easyUI+SpringMVC實現登陸認證

  最近在作一個小項目,其中認證這塊使用shiro+SpringMVC+easyUI,由於easyUI在提交數據的時候使用的是ajax的異步提交,因此shiro在處理數據的時候須要重寫FormAuthenticationFilter的相關方法,因此在此記錄下實現的過程,以供大夥參考。
  本文只給出核心代碼,完整代碼可去本人github上查看
https://github.com/q279583842q/SRM.gitjava

ShiroLoginFilter

  由於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

/**
 * 認證和受權的自定義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;
    }

}

shiro的配置文件

在這裏插入圖片描述

easyUI中提交數據

$.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

相關文章
相關標籤/搜索