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"; //退出后返回到登陆页
    }
相关文章
相关标签/搜索