4.1、认证
身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式就是通过核对用户输入的用户名和口令,看其与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。
4.2、shiro认证关键对象
-
subject:主体
访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体。
-
Principal:身份信息
主体(Subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮件地址等,一个主体可以有多个身份,但必须有一个主身份(Primary Principal)。
-
credential:凭证信息
只有主体自己知道的安全信息,比如密码、证书等
4.3、认证流程
4.4、认证开发
1、创建项目并引入依赖
添加resource目录
<!--引入-Shrio-开始-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.5.3</version>
</dependency>
<!--引入-Shrio-结束-->
2、引入shiro配置文件并加入如下配置
shiro配置文件以ini结尾,.ini复杂数据格式
创建配置文件shiro.ini
ini配置文件,用来给学习shiro书写相关权限数据,后期整合spring不用书写
#相当于配了三个用户
[users]
xiaochen=123
zhangsan=123456
lisi=789
3、认证代码
package org.hz52;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
/**
* @Program: shiro_demo
* @Description:
* @Author: 52Hz
* @CreationTime: 2021年10月16日 13:12 星期六
**/
public class testAuthenticator {
public static void main(String[] args) {
//1.创建安全管理器
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//2、给安全管理器设置realm:设置为ini里面的数据
securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
//3、SecurityUtils 给全局安全工具类设置安全管理器
SecurityUtils.setSecurityManager(securityManager);
//4、关键对象 : subject主体
Subject subject = SecurityUtils.getSubject();
//5、创建令牌
UsernamePasswordToken token = new UsernamePasswordToken("xiaochen", "123");
try {
System.out.println("认证状态:" + subject.isAuthenticated());
subject.login(token);//用户认证
System.out.println("认证状态:" + subject.isAuthenticated());
} catch (UnknownAccountException e) {
e.printStackTrace();
System.out.println("认证失败:" + token.getUsername() + "用户名不存在");
} catch (IncorrectCredentialsException e) {
e.printStackTrace();
System.out.println("认证失败:" + token.getUsername() + "密码错误");
} catch (Exception e) {
e.printStackTrace();
}
}
}
查看类的关系图
查看实现类
4.5、自定义Realm
上面的程序使用Shiro自带的IniRealm,Inirealm从配置文件中读取用户的信息,大部分情况下需要从系统的数据库中用户信息,所以需要自定义realm。
1、shiro提供的Realm
2、根据源码认证使用的是SimpleAcSimcountRealm
SimpleAcSimcountRealm的部分源码中有两个方法:一个是认证,一个是授权
2、自定义Realm
package org.hz52.realm;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/**
* @Program: shiro_demo
* @Description: 自定义Realm,将认证/授权数据来源转为数据库的实现
* @Author: 52Hz
* @CreationTime: 2021年10月16日 14:44 星期六
**/
public class CustmerRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//在token中获取用户名
String principal = (String) token.getPrincipal();
System.out.println(principal);
//根据用户身份信息使用jdbc mybatis查询相关数据库
if ("xiaochen".equals(principal)) {
//SimpleAuthenticationInfo
// 参数1:数据库中的用户名
// 参数2:数据库中的密码
// 参数3:当前realm的名称this.getName()
SimpleAuthenticationInfo simpleAuthenticationInfo