前言
上一篇介绍了Shiro的架构,我们可以发现Shiro核心的东西并不多,我们花个几分钟就可以把Shiro的机构记清楚,其中Security Manager就是Shiro的核心,他包含了身份认证器Authenticator、授权器Authorizer、Session管理Session Manager、缓存管理Cache Manager。这一篇我们就介绍下Shiro的身份认证的过程,也就是我们说的用户登录。
使用Shiro进行身份认证
1.什么是身份认证?
身份认证就是根据用户输入的用户名密码对数据库中存储的用户信息进行比对,一致则认证成功,否则失败,Shiro的配置文件是.ini结尾的文件用以存储用户信息,权限信息等,注意该文件只是用于测试场景,真正开发中是不会使用该文件的,在实际项目中这些信息都是数据库存储,不会再配置文件写死。
2.身份认证必须要知道的对象
我们已经知道,身份认证要依赖Subject(主体)来完成,主体中携带的是用户的信息与密码。所以对于这两部分我们也是要了解的。
1.Principal /ˈprɪnsəpl/ :主要因素,这里指的是登录的用户信息,也就是要用户名,一个主体可以有多个principal,比如用户名、手机号、邮箱等,但是必须有一个是2.Primary Principal。
credential /krəˈdenʃl/ :证书,这里指的是口令,也就是登录的密码。
3.认证的流程
如上图所示,Subject拿到用户信息与口令,将这些信息打包成一个令牌Token,将令牌信息再交给Security Manager中的Authenticator,对其进行身份验证,然后就会进入到系统中。
二.使用Shiro实现登录功能
1.Shiro所依赖的jar包
我们这里只需要导入其核心包,在pom文件中添加以下依赖,版本自己选择,1系列的版本差距不是很大,这里演示使用1.5.3版本。
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.5.3</version> </dependency>
2.创建一个maven工程
第一步建立工程我们使用快速开始的选项创建工程,如下:
第二步,在项目的根目录下创建resources文件用于存放.ini文件,同时创建shiro.ini的Shiro的配置文件。注意文件名无所谓,没有强制的命名规则。
第三步:书写配置文件,在配置文件中加入以下信息,第一行代表下面配置的是用户与密码的键值对。
[users] zhaoyun=daye huangzhong=sheshou
第四步:在pom.xml文件中加入上方的依赖,如下图
到这里为止,我们需要的配置都已经齐全,下面就可以写代码了。
第五步:写代码,代码展示如下:
public class TestAuthenticator { public static void main(String[] args) { //第一步,获取Security Manager DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(); //第二步,使用Security Manager加载配置文件,注意前面已经说过Realm是身份认证与权限的数据获取的地方,所以调用setRealm defaultSecurityManager.setRealm(new IniRealm("classpath:shiro.ini")); //第三步,使用SecurityUtils获取Subject SecurityUtils.setSecurityManager(defaultSecurityManager); Subject subject = SecurityUtils.getSubject(); //第四步,获取用户登录Token UsernamePasswordToken authenticationToken = new UsernamePasswordToken("zhaoyun","daye"); try { System.out.println(subject.isAuthenticated()); //第五步,登录 subject.login(authenticationToken); System.out.println(subject.isAuthenticated()); } catch (UnknownAccountException e) { e.printStackTrace(); }catch(IncorrectCredentialsException e){ e.printStackTrace(); }catch(Exception e){ e.printStackTrace(); } } }
上方代码的输出结果如下:
false true Process finished with exit code 0
3.代码实现解读
代码中已经划分好了每一步,值得说的是第一步中我们使用的是DefaultSecurityManager,而不是SecurityManager,DefaultSecurityManager是他的实现类,所以这里使用DefaultSecurityManager第五步的登录,该方法是没有返回值得,判定登录成功与否有两种方法,第一种就是判断程序有没有异常出现,当用户名异常时程序会报:UnknownAccountException,当用户输入的密码有误时会报:IncorrectCredentialsException。第二种我们可以调用isAuthenticated方法,该方法返回一个boolean的值,true表示验证通过,我们可以看到,在登录之前返回false,登录后就是true了,这就表示登录成功了。
三.总结
到这里我们就实现了一个简单的登录功能。不过这只是一个demo只包含了登录,在实际的项目中会有比这复杂的多的操作,这篇介绍完了身份验证,下一篇会继续探讨怎么通过自定义Realm来实现用户登录功能。