Shiro快速入門 —— 4.登錄認證(身份驗證)

本系列博文目錄:http://www.javashuo.com/article/p-ewndobct-kn.htmljava

 

登錄認證用於登陸時驗證登錄者的身份真實性。apache

咱們能夠經過 CA證書或用戶名密碼等方式進行認證。數組

重寫認證方法

shiro不會爲咱們提供現成的認證規則,須要咱們本身編寫認證規則。安全

編寫認證規則時咱們須要繼承AuthorizingRealm類,並實現doGetAuthenticationInfo抽象方法。app

public class ShiroRealm extends AuthorizingRealm {

    /**
     * 登陸認證(身份驗證)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        /**
         * 本身實現的認證規則
         */
    }
}

 

認證經過

認證信息若是符合認證規則,則認證經過。ide

認證經過時須要返回一個認證信息接口AuthenticationInfo的實現類SimpleAuthenticationInfo 工具

/**
     * 登陸認證(身份驗證)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        CaptchaAuthenticationToken authenticationToken = (CaptchaAuthenticationToken) token; //得到登陸令牌
        String username = authenticationToken.getUsername();
        String password = new String(authenticationToken.getPassword());//將char數組轉換成String類型
        String captchaId = authenticationToken.getCaptchaId();
        String captcha = authenticationToken.getCaptcha();
        // 驗證用戶名密碼和驗證碼是否正確
        usernamePasswordAndCaptchaAuthentication(username,password,captchaId,captcha);
        //建立身份信息類(自定義的)
        Principal principal = new Principal(1L, username);
        //認證經過返回認證信息類
        return new SimpleAuthenticationInfo(principal, password, getName());
    }

 

認證失敗

認證信息若是不符合認證規則,則認證不經過。url

認證不經過時拋出AuthenticationException異常或他的子類。spa

拋出異常後程序會進入到提交表單時指定的登陸方法,在這裏能夠經過.net

(String) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME)

來得到異常類型,經過異常類型咱們就能夠判斷異常的緣由,從而進行提示或處理。

此方法只有在認證失敗後纔會訪問,認證成功後會直接訪問配置中指定的登錄成功路徑。

/**
     * LoginController中的登陸表單提交
     * @param request
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(HttpServletRequest request, RedirectAttributes redirectAttributes) {
        //若是認證未經過得到異常並重定向到登陸頁
        String message = null;
        String loginFailure = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);//取得登錄失敗異常

        if (loginFailure.equals("pub.lichao.shiro.shiro.CaptchaAuthenticationException")) {
            message = "驗證碼錯誤";//自定義登錄認證異常 - 用於驗證碼錯誤提示
        } else if (loginFailure.equals("org.apache.shiro.authc.UnknownAccountException")) {
            message = "用戶不存在";//未找到帳戶異常
        }else if (loginFailure.equals("org.apache.shiro.authc.IncorrectCredentialsException")) {
            message = "密碼錯誤";//憑證(密碼)錯誤異常
        } else if (loginFailure.equals("org.apache.shiro.authc.AuthenticationException")) {
            message = "帳號認證失敗";//認證異常
        }else{
            message = "未知認證錯誤";//未知認證錯誤
        }

        //重定向參數傳遞,可以將參數傳遞到最終頁面
        // (用addAttribute的時候參數會寫在url中因此要用addFlashAttribute)
        redirectAttributes.addFlashAttribute("message", message);
        return "redirect:login";

    }

 

認證失敗異常

shiro默認的登錄失敗異常主要有如下這些

org.apache.shiro.authc.AuthenticationException     //認證異常
      |--org.apache.shiro.authc.AccountException      //帳戶異常

            |--org.apache.shiro.authc.ConcurrentAccessException  //單點登陸時帳戶多處登錄異常

            |--org.apache.shiro.authc.DisabledAccountException  //帳戶禁用異常

                  |--org.apache.shiro.authc.LockedAccountException   //帳戶鎖定異常

            |--org.apache.shiro.authc.ExcessiveAttemptsException  //登錄錯誤次數超限異常

            |--org.apache.shiro.authc.UnknownAccountException  //未找到帳戶異常

      |--org.apache.shiro.cas.CasAuthenticationException     //CAS證書異常

      |--org.apache.shiro.authc.CredentialsException     //憑證(密碼)異常

            |--org.apache.shiro.authc.ExpiredCredentialsException  //憑證(密碼)過時異常

            |--org.apache.shiro.authc.IncorrectCredentialsException //憑證(密碼)錯誤異常

      |--org.apache.shiro.authc.pam.UnsupportedTokenException     //令牌異常

若是這些異常沒法描述自定義規則中的某種錯誤,咱們能夠經過繼承AuthenticationException方式,編寫本身的認證異常。例如驗證碼錯誤異常

package pub.lichao.shiro.shiro;

import org.apache.shiro.authc.AuthenticationException;

/**
 * 自定義登錄認證異常 - 用於驗證碼錯誤提示
 */
public class CaptchaAuthenticationException extends AuthenticationException {
}

 

 

完整的登陸例子

實現AuthorizingRealm類的doGetAuthorizationInfo方法,編寫本身的認證規則

/**
     * 登陸認證(身份驗證)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        CaptchaAuthenticationToken authenticationToken = (CaptchaAuthenticationToken) token; //得到登陸令牌
        String username = authenticationToken.getUsername();
        String password = new String(authenticationToken.getPassword());//將char數組轉換成String類型
        String captchaId = authenticationToken.getCaptchaId();
        String captcha = authenticationToken.getCaptcha();
        // 驗證用戶名密碼和驗證碼是否正確
        usernamePasswordAndCaptchaAuthentication(username,password,captchaId,captcha);
        //建立身份信息類(自定義的)
        Principal principal = new Principal(1L, username);
        //認證經過返回認證信息類
        return new SimpleAuthenticationInfo(principal, password, getName());
    }

自定義的登陸認證異常

package pub.lichao.shiro.shiro;

import org.apache.shiro.authc.AuthenticationException;

/**
 * 自定義登錄認證異常 - 用於驗證碼錯誤提示
 */
public class CaptchaAuthenticationException extends AuthenticationException {
}

提交表單時指定的登陸方法

/**
     * LoginController中的登陸表單提交
     * @param request
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(HttpServletRequest request, RedirectAttributes redirectAttributes) {
        //若是認證未經過得到異常並重定向到登陸頁
        String message = null;
        String loginFailure = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);//取得登錄失敗異常

        if (loginFailure.equals("pub.lichao.shiro.shiro.CaptchaAuthenticationException")) {
            message = "驗證碼錯誤";//自定義登錄認證異常 - 用於驗證碼錯誤提示
        } else if (loginFailure.equals("org.apache.shiro.authc.UnknownAccountException")) {
            message = "用戶不存在";//未找到帳戶異常
        }else if (loginFailure.equals("org.apache.shiro.authc.IncorrectCredentialsException")) {
            message = "密碼錯誤";//憑證(密碼)錯誤異常
        } else if (loginFailure.equals("org.apache.shiro.authc.AuthenticationException")) {
            message = "帳號認證失敗";//認證異常
        }else{
            message = "未知認證錯誤";//未知認證錯誤
        }

        //重定向參數傳遞,可以將參數傳遞到最終頁面
        // (用addAttribute的時候參數會寫在url中因此要用addFlashAttribute)
        redirectAttributes.addFlashAttribute("message", message);
        return "redirect:login";

    }


 

退出登陸

退出登陸時只要使用Subject的logout()方法便可。

/**
     * 退出登陸
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(RedirectAttributes redirectAttributes) {
        //調用shiro管理工具類的退出登陸方法
        SecurityUtils.getSubject().logout();
        redirectAttributes.addFlashAttribute("message", "您已安全退出");
        return "redirect:login"; //退出後返回到登陸頁
    }
相關文章
相關標籤/搜索