根据B站不良人的Shiro随堂代码
认证
使用ini方式
在resources下创建shiro.ini数据如下
[users]
xiaowu=123
zhangsan=123456
lisi=789
创建TestAuthenticator测试
package com.baizhi;
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.mgt.SecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
public class TestAuthenticator {
public static void main(String[] args) {
//1.创建安全管理器
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//2.给安全管理器设置realm
securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
//3.SecurityUtils 给全局工具类设置安全管理器
SecurityUtils.setSecurityManager(securityManager);
//4.关键对象 subject主体
Subject subject = SecurityUtils.getSubject();
//5.创建令牌
UsernamePasswordToken token = new UsernamePasswordToken("xiaowu","123");
try {
System.out.println("认证状态:"+subject.isAuthenticated());
subject.login(token);
System.out.println("认证状态:"+subject.isAuthenticated());
}catch (UnknownAccountException e){
e.printStackTrace();
System.out.println("用户名不正确");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码不正确");
}
}
}
自定义Realm
自定义CustomerRealm类继承AuthorizingRealm 重写doGetAuthorizationInfo,doGetAuthenticationInfo方法,doGetAuthorizationInfo用于权限,doGetAuthenticationInfo用于认证
package com.baizhi.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.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.UUID;
/**
* 自定义Realm继承AuthorizingRealm
* 重写doGetAuthorizationInfo,doGetAuthenticationInfo方法
*/
public class CustomerRealm extends AuthorizingRealm {
//用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//用于认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//从token中获取用户名
String principal = (String) authenticationToken.getPrincipal();
//判断用户名是否相等
if("xiaowu".equals(principal)){
//SimpleAuthenticationInfo相当于数据库中查询出固有的数据
//SimpleAuthenticationInfo中的三个参数 1.用户名 2.密码 3.提供当前realm的名字,写this.getName()
return new SimpleAuthenticationInfo(principal,"123",this.getName());
}
return null;
}
//给密码添加随机盐
public static void main(String[] args) {
String yan = UUID.randomUUID().toString().substring(0,5).replace("-","");
System.out.println(yan);
String mima = "3232"+yan;
Md5Hash md5Hash = new Md5Hash(mima);
System.out.println(md5Hash);
}
}
创建测试类TestCustomerRealmAuthenticator进行测试
package com.baizhi;
import com.baizhi.realm.CustomerRealm;
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.subject.Subject;
import java.security.Security;
public class TestCustomerRealmAuthenticator {
public static void main(String[] args) {
//创建SecurityManager
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//设置自定义realm获取认证数据
defaultSecurityManager.setRealm(new CustomerRealm());
//将安装工具类中设置默认安全管理器
SecurityUtils.setSecurityManager(defaultSecurityManager);
//获取主体对象
Subject subject = SecurityUtils.getSubject();
//获取token令牌
UsernamePasswordToken token = new UsernamePasswordToken("xiaowu","123");
try {
System.out.println(subject.isAuthenticated());
subject.login(token);
System.out.println(subject.isAuthenticated());
System.out.println("认证通过");
}catch (UnknownAccountException e){
e.printStackTrace();
System.out.println("用户名错误");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误");
}
}
}
自定义Realm并且加密,加盐,加散列
自定义CustomerMd5Realm类继承AuthorizingRealm 重写doGetAuthorizationInfo,doGetAuthenticationInfo方法,doGetAuthorizationInfo用于权限,doGetAuthenticationInfo用于认证
package com.baizhi.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;
import org.apache.shiro.util.ByteSource;
/**
* 自定义realm进行数据加密
*/
public class CustomerMd5Realm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//获取用户名
String principal = (String) authenticationToken.getPrincipal();
if("xiaowu".equals(principal)){
//参数1:传过来的用户名 参数2:数据库中加密加盐的密码 参数3:盐值 参数4:realm的名字
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
principal,
"ebfba174f6bfe6d28f94db321cf899e2",
ByteSource.Util.bytes("xiaowu"),
this.getName());
return simpleAuthenticationInfo;
}
return null;
}
}
创建测试类TestCustomerMd5RealmAuthenticator进行测试
package com.baizhi;
import com.baizhi.realm.CustomerMd5Realm;
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.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
public class TestCustomerMd5RealmAuthenticator {
public static void main(String[] args) {
//创建安全管理器
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//创建CustomerMd5Realm对象
CustomerMd5Realm realm = new CustomerMd5Realm();
//设置realm使用hash凭证匹配器
//创建hash凭证器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//加密的方式(使用的算法)
credentialsMatcher.setHashAlgorithmName("md5");
//散列的次数
credentialsMatcher.setHashIterations(1024);
//设置realm使用hash凭证匹配器
realm.setCredentialsMatcher(credentialsMatcher);
//注入Realm
defaultSecurityManager.setRealm(realm);
//将安全管理器注入工具类
SecurityUtils.setSecurityManager(defaultSecurityManager);
//通过安全管理器获得Subject
Subject subject = SecurityUtils.getSubject();
//获得令牌
UsernamePasswordToken token = new UsernamePasswordToken("xiaowu","123");
//认证
try {
subject.login(token);
System.out.println("登陆成功");
System.out.println(subject.isAuthenticated());
}catch (UnknownAccountException e){
System.out.println("用户名不正确");
e.printStackTrace();
}catch (IncorrectCredentialsException e){
System.out.println("密码不正确");
e.printStackTrace();
}
}
}
授权
基于自定义Realm并且加密,加盐,加散列
自定义CustomerMd5Realm类继承AuthorizingRealm 重写doGetAuthorizationInfo,doGetAuthenticationInfo方法,doGetAuthorizationInfo用于权限,doGetAuthenticationInfo用于认证
package com.baizhi.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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
/**
* 自定义realm进行数据加密
*/
public class CustomerMd5Realm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取当前的用户名
String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
System.out.println("认证信息:"+primaryPrincipal);
//根据当前身份信息,用户名,获取当前用户的角色信息,以及权限信息 xiaowu admin user
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//根据数据库中查询的角色信息赋值给当前对象
simpleAuthorizationInfo.addRole("admin");
simpleAuthorizationInfo.addRole("user");
//将数据库中查询权限信息赋值给权限对象
//对user模块中01的全部权限
simpleAuthorizationInfo.addStringPermission("user:*:01");
//对商品模块的添加权限
simpleAuthorizationInfo.addStringPermission("product:create");
return simpleAuthorizationInfo;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//获取用户名
String principal = (String) authenticationToken.getPrincipal();
if("xiaowu".equals(principal)){
//参数1:传过来的用户名 参数2:数据库中加密加盐的密码 参数3:盐值 参数4:realm的名字
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
principal,
"ebfba174f6bfe6d28f94db321cf899e2",
ByteSource.Util.bytes("xiaowu"),
this.getName());
return simpleAuthenticationInfo;
}
return null;
}
}
创建测试类TestCustomerMd5RealmAuthenticator进行测试
package com.baizhi;
import com.baizhi.realm.CustomerMd5Realm;
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.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import java.util.Arrays;
public class TestCustomerMd5RealmAuthenticator {
public static void main(String[] args) {
//创建安全管理器
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//创建CustomerMd5Realm对象
CustomerMd5Realm realm = new CustomerMd5Realm();
//设置realm使用hash凭证匹配器
//创建hash凭证器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//加密的方式(使用的算法)
credentialsMatcher.setHashAlgorithmName("md5");
//散列的次数
credentialsMatcher.setHashIterations(1024);
//设置realm使用hash凭证匹配器
realm.setCredentialsMatcher(credentialsMatcher);
//注入Realm
defaultSecurityManager.setRealm(realm);
//将安全管理器注入工具类
SecurityUtils.setSecurityManager(defaultSecurityManager);
//通过安全管理器获得Subject
Subject subject = SecurityUtils.getSubject();
//获得令牌
UsernamePasswordToken token = new UsernamePasswordToken("xiaowu","123");
//认证
try {
subject.login(token);
System.out.println("登陆成功");
System.out.println(subject.isAuthenticated());
}catch (UnknownAccountException e){
System.out.println("用户名不正确");
e.printStackTrace();
}catch (IncorrectCredentialsException e){
System.out.println("密码不正确");
e.printStackTrace();
}
//权限的控制,是在认证通过之后
if(subject.isAuthenticated()){
//基于单角色的权限控制
boolean danjuese = subject.hasRole("admin");
System.out.println("单角色:"+danjuese);
//基于多角色的权限控制,同时拥有以下两个权限返回true
boolean duojuese = subject.hasAllRoles(Arrays.asList("admin","user"));
System.out.println("多角色:"+duojuese);
//基于任意其中之一的角色,哪一个满足,哪一个就返回true,否则返回false
boolean[] renyijuese = subject.hasRoles(Arrays.asList("admin", "super", "user"));
for (boolean r:renyijuese){
System.out.println("任意角色:"+r);
}
System.out.println("====================================================");
//基于权限字符串的控制 资源标识符:操作:资源类型
//user的修改权限
boolean permitted1 = subject.isPermitted("user:update:01");
System.out.println("user中01的修改权限:"+permitted1);
//product的修改权限
boolean permitted2 = subject.isPermitted("product:update");
System.out.println("product的修改权限:"+permitted2);
//product的02的增加权限
boolean permitted3 = subject.isPermitted("product:create:02");
System.out.println("product中02的增加权限:"+permitted3);
//分别具有那些权限 有的返回true,没有返回false
boolean[] permitted4 = subject.isPermitted("user:*:01", "order:*");
for (boolean b : permitted4) {
System.out.println("分别有哪些权限:"+b);
}
//同时具有哪些权限 有以下所有权限返回true,否则返回false
boolean permittedAll = subject.isPermittedAll("user:*:01", "product:create");
System.out.println("同时具有哪些权限:"+permittedAll);
}
}
}