个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~
principals(身份)
和credentials(证明)
给shiro,从而shiro对用户进行身份验证。principals(身份)
:是主体的标识属性,可以是任何属性,如:用户名、email等,保证唯一即可。一份主体可以有多个principals
,但是只有一个Primary principals
,一般是用户名/邮箱/手机号。credentials(证明)
:证明/凭证,是只有主体知道的安全值,如:密码、数字证书。基本流程
:
Subject.login()
进行登录,如果失败将得到对应的AuthenticationException异常
,可根据异常提示用户错误信息;否则登录成功Realm
类,继承 org.apache.shiro.realm.AuthenticatingRealm
类,实现 doGetAuthenticationInfo()
方法导入坐标
:
<!-- shiro-core -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
配置ini文件
:
# Shiro获取权限相关信息可以通过数据库获取,也可以通过ini文件获取
# 配置账户密码信息
[users]
userA = 123a
userB = 123b
测试案例
:
/**
* @author .29.
* @create 2024-03-16 16:54
*/
public class shiroRun {
public static void main(String[] args){
//1. 初始化获取安全管理器SecurityManager
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:Shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//2. 获取Subject对象
Subject subject = SecurityUtils.getSubject();
//3. 创建token对象,web应用用户名密码从页面传递
UsernamePasswordToken token = new UsernamePasswordToken("userA", "123a");
//如果希望应用程序在用户返回时记住用户,可以使用令牌的setRememberMe()方法,并设置参数为true
token.setRememberMe(true);
//4. 完成登录
//你可以接受该方法调用并将其包装在 try/catch 块中,如果你想处理它们并做出相应的反应,你可以捕获各种异常。
try{
subject.login(token);
System.out.println("登陆成功!");
}catch (UnknownAccountException e){
e.printStackTrace();
System.out.println("用户不存在!");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误!");
}catch (AuthenticationException ae){
//这个块捕获了所有的认证异常,
//表达的意思是,以此类推,你可以通过捕获异常的方式来处理逻辑
}
}
}
Subject.login(token)
进行登录,其会自动委托给 SecurityManager
;SecurityManager
负责真正的身份验证逻辑;它会委托给 Authenticator
进行身份验证;Authenticator
可能会委托给相应的 AuthenticationStrategy
进行多 Realm 身份验证,默认 ModularRealmAuthenticator
会调用 AuthenticationStrategy
进行多 Realm身份验证;Authenticator
会把相应的 token
传入 Realm
,从 Realm
获取身份验证信息,如果没有返回/抛出异常 就表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。导入坐标
:
<!-- shiro-core -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
自定义Realm进行登录认证
:
/**
* @author .29.
* @create 2024-03-16 19:08
* 1.自定义Realm进行登录认证,配置好后Shiro的Subject.login()方法底层会调用该类的认证方法完成登录认证
* 2.想要自定义的 realm 生效,需要在 ini 文件或 Springboot配置文件在中进行相关配置配置
* 3.该方法只是获取进行对比的信息,认证逻辑还是按照 Shiro 的底层认证逻辑完成认证
*/
public class myRealm extends AuthenticatingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1. 通过token获取身份信息
String principal = authenticationToken.getPrincipal().toString();
//2. 通过token获取凭证信息
String credentials = new String((char[]) authenticationToken.getCredentials());
System.out.println("认证用户信息:"+principal+"---"+credentials);
//3. 获取数据库中存储的用户信息
if(principal.equals("userA")){
//3.1模拟从数据库中获取到MD5加盐嵌套3次加密的密码
String pwd = "e8e2ea5deb7e981462ab88c2b7e3f19a";
//3.2创建封装了校验逻辑的对象,将需要校验的数据传进去
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
authenticationToken.getPrincipal()//身份
, pwd//数据库中存放的密码
, ByteSource.Util.bytes("salt")//MD5加盐的“盐”
, authenticationToken.getPrincipal().toString()
);
return info;//返回封装了校验逻辑的对象
}
return null;
}
}
配置ini文件
:
# Shiro获取权限相关信息可以通过数据库获取,也可以通过ini文件获取
#添加配置,配置解密MD5的循环次数,配置使用自定义的Realme进行登录校验,
[main]
md5CredentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations=3
myrealm=com.to9.test.myRealm
myrealm.credentialsMatcher=$md5CredentialsMatcher
securityManager.realms=$myrealm
# 配置账户密码信息,密码是"123456789"MD5加盐加密3次的结果,盐为"salt"
[users]
userA = e8e2ea5deb7e981462ab88c2b7e3f19a
测试案例
:
/**
* @author .29.
* @create 2024-03-16 16:54
*/
public class shiroRun {
public static void main(String[] args){
//1. 初始化获取安全管理器SecurityManager
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:Shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//2. 获取Subject对象
Subject subject = SecurityUtils.getSubject();
//3. 创建token对象,web应用用户名密码从页面传递
UsernamePasswordToken token = new UsernamePasswordToken("userA", "123456789");
//如果希望应用程序在用户返回时记住用户,可以使用令牌的setRememberMe()方法,并设置参数为true
token.setRememberMe(true);
//4. 完成登录
//你可以接受该方法调用并将其包装在 try/catch 块中,如果你想处理它们并做出相应的反应,你可以捕获各种异常。
try{
subject.login(token);
System.out.println("登陆成功!");
}catch (UnknownAccountException e){
e.printStackTrace();
System.out.println("用户不存在!");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误!");
}catch (AuthenticationException ae){
//这个块捕获了所有的认证异常,
//表达的意思是,以此类推,你可以通过捕获异常的方式来处理逻辑
}
}
}