1. 程式人生 > >shiro基於表單的攔截器身份驗證、基於 Basic 的攔截器身份驗證,普通身份驗證的區別

shiro基於表單的攔截器身份驗證、基於 Basic 的攔截器身份驗證,普通身份驗證的區別

目錄

普通身份驗證與基於表單的攔截器、基於basic的攔截器身份驗證的區別?

普通身份驗證的一個缺點就是,永遠返回到同一個成功頁面(比如首頁),在實際專案中比如支付時如果沒有登入將跳轉到登入頁面,登入成功後再跳回到支付頁面;對於這種功能大家可以在登入時把當前請求儲存下來,然後登入成功後再重定向到該請求即可。

Shiro 內建了登入(身份驗證)的實現:基於表單的和基於 Basic 的驗證,其通過攔截器實現。成功後會自動返回上一個頁面,而不是直接跳轉到首頁或者登陸成功頁面

普通身份驗證程式碼如下,需要用程式碼跳轉到登入成功的頁面

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String error = null;
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(true);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            error = "使用者名稱/密碼錯誤";
        } catch (IncorrectCredentialsException e) {
            error = "使用者名稱/密碼錯誤";
        } catch (AuthenticationException e) {
            //其他錯誤,比如鎖定,如果想單獨處理請單獨catch處理
            error = "其他錯誤:" + e.getMessage();
        }

        if(error != null) {//出錯了,返回登入頁面
            req.setAttribute("error", error);
            req.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(req, resp);
        } else {//登入成功
            req.getRequestDispatcher("/WEB-INF/jsp/loginSuccess.jsp").forward(req, resp);
        }
    }

基於表單的攔截器身份驗證和基於 Basic 的攔截器身份驗證的區別

首先這是普通驗證的ini檔案關於攔截器的配置

[main]
#預設是/login.jsp
authc.loginUrl=/login
roles.unauthorizedUrl=/unauthorized
perms.unauthorizedUrl=/unauthorized

logout.redirectUrl=/login

這是基於表單的攔截器身份驗證

[main]
#authc 是 org.apache.shiro.web.filter.authc.FormAuthenticationFilter 型別的例項,其用於實現基於表單的身份驗證
authc.loginUrl=/formfilterlogin
authc.usernameParam=username
authc.passwordParam=password
authc.successUrl=/
authc.failureKeyAttribute=shiroLoginFailure

perms.unauthorizedUrl=/unauthorized
roles.unauthorizedUrl=/unauthorized

ini檔案中基於表單攔截器的驗證與普通攔截器驗證的區別體現在後端的判斷上

這是普通攔截器的後端判斷程式碼,需要用程式碼去獲取前端使用者名稱與密碼屬性的值,再去生成token與subject.login對比

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String error = null;
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(true);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            error = "使用者名稱/密碼錯誤";
        } catch (IncorrectCredentialsException e) {
            error = "使用者名稱/密碼錯誤";
        } catch (AuthenticationException e) {
            //其他錯誤,比如鎖定,如果想單獨處理請單獨catch處理
            error = "其他錯誤:" + e.getMessage();
        }

        if(error != null) {//出錯了,返回登入頁面
            req.setAttribute("error", error);
            req.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(req, resp);
        } else {//登入成功
            req.getRequestDispatcher("/WEB-INF/jsp/loginSuccess.jsp").forward(req, resp);
        }
    }

這是基於表單攔截器的後端驗證,shiro會自動去驗證使用者密碼的正確性,如果錯誤則丟擲異常名字,寫入req的屬性中,屬性名通過ini配置檔案的authc.failureKeyAttribute=shiroLoginFailure指定,failureKeyAttribute 指定登入失敗時的 request 屬性 key(預設 shiroLoginFailure)

import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String errorClassName = (String)req.getAttribute("shiroLoginFailure");

        if(UnknownAccountException.class.getName().equals(errorClassName)) {
            req.setAttribute("error", "使用者名稱/密碼錯誤");
        } else if(IncorrectCredentialsException.class.getName().equals(errorClassName)) {
            req.setAttribute("error", "使用者名稱/密碼錯誤");
        } else if(errorClassName != null) {
            req.setAttribute("error", "未知錯誤:" + errorClassName);
        }

        req.getRequestDispatcher("/WEB-INF/jsp/formfilterlogin.jsp").forward(req, resp);
    }

對於表單與basic攔截器驗證來說,登入成功會自動跳轉到上一個頁面,不用在程式碼裡面體現