引入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
开发方式
使用系统数据源开发
- 开发数据源配置文件 shiro-permission.ini
[users]
libai=123456,role1,role2
zhangfei=123456,role2
[roles]
role1=user:create,user:update
role2=user:create,user:delete
role3=user:create,emp:create
- 基于角色的授权
/**
* 作用:基于角色的授权 Role-Based Access Control
* 作者:gjx
* 版本:V1.0
*
*/
public class TestRBACByRole {
public static void main(String[] args) {
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
subject.login(new UsernamePasswordToken("libai","123456"));
//用户授权检测
//查询当前用户有没有这个角色
boolean role1 = subject.hasRole("role3");
System.out.println(role1);
//查询当前用户是否有多个角色
boolean[] booleans = subject.hasRoles(Arrays.asList("role1", "role2", "role3"));
for (boolean aBoolean : booleans) {
System.out.println(aBoolean);
}
//查询当前用户是否同时具有这些角色
boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1", "role2", "role3"));
System.out.println(hasAllRoles);
}
}
- 基于资源的授权
/**
* 作用:基于资源的授权 Resource-Based Access Control
* 作者:gjx
* 版本:V1.0
*
*/
public class TestRBACByResources {
public static void main(String[] args) {
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
//认证
subject.login(new UsernamePasswordToken("libai","123456"));
//用户授权检测
//查询是否含有某个权限
boolean permitted = subject.isPermitted("user:create");
System.out.println(permitted);
//查询当前用户是否同时含有多个权限
boolean permittedAll = subject.isPermittedAll("user:create", "user:update");
System.out.println(permittedAll);
}
}
使用自定义数据源开发
- 开发自定义数据源
/**
* 作用: 自定义数据源
* 作者:gjx
* 版本:V1.0
*/
public class MyRealm extends AuthorizingRealm {
/**
* 获取授权信息 角色信息+权限信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = (String) principalCollection.getPrimaryPrincipal();
if("libai".equals(username)){
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRole("root");
info.addRole("admin");
info.addRole("user");
info.addStringPermission("user:add");
info.addStringPermission("user:query");
info.addStringPermission("user:remove");
return info;
}
return null;
}
/**
* 获取认证信息方法
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("**********");
UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken)authenticationToken;
String username = usernamePasswordToken.getUsername();
if("libai".equals(username)){
return new SimpleAuthenticationInfo("libai","3d53b73c485f523ef2fe45f2b8dd3c58",ByteSource.Util.bytes("ABCD"),UUID.randomUUID().toString());
}
return null;
}
}
- 开发数据源配置文件 shiro-md5Realm.ini
[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#定义散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=1024
#将凭证匹配器设置到realm中
myRealm=cn.gjxblog.demo3.CustomMD5Realm
myRealm.credentialsMatcher=$credentialsMatcher
#将realm设置到securityManager中
securityManager.realms=$myRealm
- 开发程序
/**
* 作用:基于资源的授权, Resource-Based Access Control
* 作者:gjx
* 版本:V1.0
*/
public class TestRBACByResources2 {
public static void main(String[] args) {
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-md5Realm.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
subject.login(new UsernamePasswordToken("libai","123456"));
//用户授权检测
//查询是否含有某个权限
boolean permitted = subject.isPermitted("user:delete");
System.out.println(permitted);
//查询当前用户是否同时含有多个权限
boolean permittedAll = subject.isPermittedAll("user:create", "user:update");
System.out.println(permittedAll);
}
}
总结
授权执行流程
1、执行subject.isPermitted(“user:create”)
2、securityManager通过ModularRealmAuthorizer进行授权
3、ModularRealmAuthorizer调用realm获取权限信息ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配
权限字符串规则
权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。
role1 = user:create role1 角色对用户资源有创建的权限
role1 = user:update:1 role1 角色对用户id为1的这个资源有修改权限
例子:
用户创建权限:user:create,或user:create:*
用户修改实例001的权限:user:update:001
用户实例001的所有权限:user:*:001