[参考]( (1条消息) Shiro 学习笔记(5)—— 自定义权限解析器和角色解析器_李威威的博客-CSDN博客_shiro 自定义权限)
背景
项目里面接口权限设计格式是METHOD:URL
对于带参的URL,其权限字符串会如GET:/api/permission/find/{id}
,Shiro默认是以冒号为分隔对每一段进行匹配,所以前端发起相应请求,后端组成的权限字符串GET:/api/permission/find/1
不会被Shrio识别为与GET:/api/permission/find/{id}
相同的权限
因此需要自定义权限认证进行匹配
解决方案
通过定义一个权限类实现 Permission
中的 implies(Permission permission)
方法来实现自定义权限认证。
在匹配时将 GET:/api/permission/find/{id}
切割为 GET:/api/permission/find/
,然后调用 GET:/api/permission/find/1
的 startsWith
方法进行匹配
PermissionCheckModel.java
权限类,定义权限匹配方法:
/**
* @Description 自定义权限字符串比较
* @Author 王星宇
* @Date 2021-11-06
* @Version 1.0
**/
public class PermissionCheckModel implements Permission , Serializable {
private String permissionStr;
public PermissionCheckModel(){}
public PermissionCheckModel(String perissionStr){
this.permissionStr = perissionStr;
}
/**
* 传进来的 GET:/api/permission/find/1 与 GET:/api/permission/find/{id} 进行比较
* @param permission GET:/api/permission/find/1
* @return
*/
@Override
public boolean implies(Permission permission) {
if(!(permission instanceof PermissionCheckModel)){
return false;
}
String permissionHave = permissionStr;
if(permissionHave.indexOf("{") > 1){
permissionHave = permissionHave.substring(0,permissionHave.indexOf("{"));
}
PermissionCheckModel model = (PermissionCheckModel)permission;
if(model.permissionStr.startsWith(permissionHave)){
return true;
}
return false;
}
}
MyPermissionResolver.java
根据传入的权限字符串选择不同的权限类,这里全部使用上面定义的 PermissionCheckModel.java
。
/**
* @Description 根据不同的接口选择使用不同的resolver
* @Author 王星宇
* @Date 2021-11-06
* @Version 1.0
**/
public class MyPermissionResolver implements PermissionResolver {
@Override
public Permission resolvePermission(String s) {
return new PermissionCheckModel(s);
}
}
ShiroConfig.java
在Shiro的配置类中配置使用定义的 MyPermissionResolver.java
@Bean
public MyPermissionResolver myPermissionResolver(){
return new MyPermissionResolver();
}
@Bean
public Realm getRealm(MyPermissionResolver myPermissionResolver){
CustomerRealm customerRealm = new CustomerRealm();
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("SHA");
customerRealm.setCachingEnabled(true);
customerRealm.setAuthenticationCachingEnabled(true);
customerRealm.setAuthorizationCachingEnabled(true);
customerRealm.setCacheManager(new RedisCacheManager());
customerRealm.setPermissionResolver(myPermissionResolver); // 使用自定义的Resolver
return customerRealm;
}
CustomerRealm.java
为用户设置权限时设置定义的 PermissionCheckModel.java
权限类
public class CustomerRealm extends AuthorizingRealm {
Logger logger = LoggerFactory.getLogger(CustomerRealm.class);
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 查询出用户权限
List<String> permissions = ;
for(String permission : permissions){
if(permission != null) {
// 为用户设置权限
info.addObjectPermission(new PermissionCheckModel(permission));
}
}
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 认证操作
}
}
版权声明:本文为w_xy999原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。