前言
本教程作者是「小灯光环」,作者简介:全栈开发工程师,CSDN博客专家,CSDN论坛 Java Web/Java EE版主,热爱技术,乐于分享,在分布式Web开发/Android开发/微信小程序开发/Linux系统优化等方面均有一定经验,欢迎点击文章底部的阅读原文关注作者博客。
公众号内回复「登陆锁定」即可获取源码。
正文
初学shiro,shiro提供了一系列安全相关的解决方案,根据官方的介绍,shiro提供了"身份认证"、"授权"、"加密"和"Session管理"这四个主要的核心功能,如下图所示:
本篇文章主要用到了Authentication(身份认证)和Cryptography(加密),并通过这两个核心模块来演示shiro如何帮助我们构建更安全的web project中的登录模块,实现了安全的密码匹配和登录失败超指定次数锁定账户这两个主要功能,下面一起来体验一下。
身份认证与加密
如果简单了解过shiro身份认证的一些基本概念,都应该明白shiro的身份认证的流程,大致是这样的:当我们调用subject.login(token)的时候,首先这次身份认证会委托给Security Manager,而Security Manager又会委托给Authenticator,接着Authenticator会把传过来的token再交给我们自己注入的Realm进行数据匹配从而完成整个认证。如果不太了解这个流程建议再仔细读一下官方提供的Authentication说明文档:
shiro.apache.org/authentication.html
接下来通过代码来看看,理论往往没有说服力,首先看一下项目结构(具体可在号内回复「登陆锁定」下载源码参考):
项目通过Maven的分模块管理按层划分,通过最常用的spring+springmvc+mybatis来结合shiro进行web最简单的登录功能的实现,首先是登录页面:
我们输入用户名和密码点击submit则跳到UserController执行登录的业务逻辑,接下来看看UserController的代码:
很简单,上面的代码在shiro官方的10min-Tutorial就有介绍,这是shiro进行身份验证时最基本的代码骨架,只不过我们集成了Spring之后就不用自己去实例化IniSecurityManagerFactory和SecurityManager了,shiro根据身份验证的结果不同会抛出各种各样的异常类,如上的几种异常是我们最常用的,如果还想了解更多相关的异常可以访问shiro官方的介绍:
http://shiro.apache.org/static/current/apidocs/org/apache/shiro/authc/AuthenticationException.html
根据shiro的认证流程,最终Authenticator会把login传入的参数token交给Realm进行验证,Realm往往也是我们自己注入的,我们在debug模式下不难发现,在subject.login(token)打上断点,F6之后会跳到我们Realm类中doGetAuthenticationInfo(AuthenticationToken token)这个回调方法,从而也验证了认证流程确实没问题。下面贴出Realm中的代码:
关于Realm我们一般都会继承AuthorizingRealm去实现我们自己的Realm类,虽然从名字看这个Realm是用于授权的,而我们此处需要用到的是身份认证,但实际上AuthorizingRealm也继承了AuthenticatingRealm,我们在源码中就可以看到:
在