本系列博文目录: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"; //退出后返回到登陆页 }