Shiro 支持三种方式的授权:
I、 编程式:通过写if/else 授权代码块完成:
Subject subject =SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}
II、 注解式:通过在执行的Java方法上放置相应的注解完成:
@RequiresRoles("admin")
public void hello() {
//有权限
}
III、 JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:
<shiro:hasRolename="admin">
<!— 有权限—>
</shiro:hasRole>
此教程序授权测试使用第一种编程方式,实际与web系统集成使用后两种方式。
权限标识符
权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。
例子:
用户创建权限:user:create,或user:create:*
用户修改实[例]()001的权限:user:update:001
用户实例001的所有权限:user:*:001
I、根据配置文件认证
[users]
zhang3=123123,normal
li4=123456,super
[roles]
# normal 具有用户的所有权限
normal=user:*
super=product:*,user:*
package com.baizhi.Authorrizer;/**
* @Author:luoht
* @Description:
* @Date:Create in 20:50 2018/12/30
*/
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import java.util.Arrays;
import java.util.List;
/**
* @program: DJ
* @description:
* @author: luoht
* @create: 2018-12-30 20:50
**/
public class TestAuthorize {
public static void main(String[] args) {
//如果授权,就先认证
IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro3.ini");
SecurityManager instance = iniSecurityManagerFactory.getInstance();
SecurityUtils.setSecurityManager(instance);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhang3", "123123");
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println(("用户名错误"));
} catch (IncorrectCredentialsException e){
System.out.println("密码错误");
}
boolean authenticated = subject.isAuthenticated();
if (authenticated){
/**
* 认证成功之后
* 编程式授权
* 1. 基于角色
* 2. 基于资源
*
*/
/* 1.1 判断当前主体是否含有某种角色*/
boolean hasRole = subject.hasRole("normal");
System.out.println(hasRole);
/* 1.2 判断当前主体是否具有某些角色*/
List<String> strings = Arrays.asList("normal", "super");
boolean[] booleans = subject.hasRoles(strings);
for (boolean aBoolean : booleans) {
System.out.println(aBoolean);
}
/* 1.3 判断当前主主体是否同时具有某些角色*/
boolean hasAllRoles = subject.hasAllRoles(strings);
System.out.println(hasAllRoles);
/* 2.1 判断当前主体是否具有某个权限*/
boolean subjectPermitted = subject.isPermitted("user:create");
System.out.println(subjectPermitted);
/* 2.2 判断当前用户书否具有某些权限*/
List<String> stringList = Arrays.asList("user:create", "product:delete");
String[] strings1={"user:create", "product:delete"};
boolean[] permitted = subject.isPermitted(strings1);
for (boolean b : permitted) {
System.out.println(b);
}
boolean permittedAll = subject.isPermittedAll(strings1);
System.out.println(permittedAll);
}
}
}
II、数据库认证
自定义Realm:
package com.baizhi.Authorrizer;/**
* @Author:luoht
* @Description:
* @Date:Create in 22:30 2018/12/30
*/
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;
/**
* @program: DJ
* @description:
* @author: luoht
* @create: 2018-12-30 22:30
**/
public class MyRealm3 extends AuthorizingRealm {
/* 授权 | Actually, I don't know what that fucking means*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
/*通过用户查询角色*/
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addRole("normal");
/*通过角色查询权限*/
return simpleAuthorizationInfo;
}
/* 认证*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String principal = (String) authenticationToken.getPrincipal();
if (principal.equals("zhang3")){
return new SimpleAuthenticationInfo("zhang3","b8cc2120cdf1554cf35603e08f7f5524", ByteSource.Util.bytes("1345"),this.getName());
}
return null;
}
}
[main]
# 声明凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
# 声明realm
realm2= com.baizhi.Authorrizer.MyRealm3
securityManager.realms=$realm2
# 告知realm使用HashedCredentialsMatcher 为凭证匹配器
realm2.credentialsMatcher=$credentialsMatcher
# 告知安全管理器使用自定义
securityManager.realms=$realm2
# 告知Shiro算法的名称
credentialsMatcher.hashAlgorithmName=md5
credentialsMatcher.hashIterations=1024
III、授权执行流程
- 执行subject.isPermitted("user:create")
- securityManager通过ModularRealmAuthorizer进行授权
- ModularRealmAuthorizer调用realm获取权限信息
ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配