前言
本文主要讲解shiro的具体认证机制,这属于shiro提供的一个最基本的功能。
Authentication首先有两个重要的概念:
- Principals : 是用来标识Subject身份的属性,可以是用户名、身份证号等值。需要注意的Shiro中最好用用户名、邮箱或者用户id作为主要标识Principal。
- Credentials : 是针对Principal具有的特定凭证,通常来说可能是密码。
Principal/Credential对组成了一个Subject用来作为认证主题,并且通常是 用户名/密码的形式。
具体认证步骤
添加依赖
<dependencies>
<!--shiro核心-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
<!--测试-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
配置【ini】
这边配置了两个用户
[users]
rose = 123
joe = 123456
核心代码
public class AuthenticationUtil {
//日志
private static final Logger logger = LoggerFactory.getLogger(AuthenticationUtil.class);
public static void authenticate(String username, String password) {
// 通过加载shiro.ini配置文件获取IniSecurityManagerFactory实例工厂,然后调用getInstance()获取SecurityManager实例
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
//设置全局共享
SecurityUtils.setSecurityManager(securityManager);
//获取当前Subject
Subject subject = SecurityUtils.getSubject();
//初始化Token信息
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
usernamePasswordToken.setRememberMe(true);
//通过令牌信息进行登录
try {
subject.login(usernamePasswordToken);
} catch (AuthenticationException e) {
//处理登录失败的逻辑
logger.info("username or password is not correct");
e.printStackTrace();
}
//登录成功
logger.info("welcome to the application!");
}
//测试
public static void main(String[] args) {
// 测试1
authenticate("joe", "123456");
// 测试2
authenticate("rose", "123456");
}
}
测试结果
测试1:
测试2:
内部流程
这部分我们来看一下在Shiro内部Authentication是如何进行的,设计组件如下图(五个部分,下面会一一讲解):
- 通过调用Subject.login(token)来触发认证,需要传入AuthenticationToken来获取相关的principal和credential
- 通过第一步后,底层会进行调用securityManager的login方法
- 通过第二步后,底层securityManager会调用authenticator.authenticate(token),典型的authenticator是ModularRealmAuthenticator可以支持可拔插式配置Realm
- 通过第三步后,authenticator会通过AuthenticationStrategy来针对不同的Realm定义不同的认证策略。
- 最后会查询配置好的realm的信息依次来进行信息匹对。
总结
本文主要讲解了Shiro进行身份验证的流程,并对底层的各个组件进行了讲解。后续文章还对针对Realm部分的配置以及源码进行分析。