-
Notifications
You must be signed in to change notification settings - Fork 122
I、鉴权规则
wangjie edited this page Dec 25, 2019
·
1 revision
权限泛指能否操作资源,角色是权限的集合。
安全模型RBAC(Role-Based Access Control 基于角色的权限访问控制),使用用户--角色--资源(URL)的对应关系来表示权限,这个对应关系通常都是持久化保存的。
提供给jsets-shiro-spring-boot-starter的权限数据,为如下格式:
使用类RolePermRule封装。
@Service
public class FilteRulesProviderImpl implements ShiroFilteRulesProvider{
@Autowired
private JdbcEnhance jdbcEnhance;
/**
* 加载基于角色/资源的权限验证
* RolePermRule包含三个属性(url:资源URL、needRoles:访问需要的角色列表、needPerms:访问需要的权限列表)
*/
@Override
public List<RolePermRule> loadRolePermRules(){
List<RolePermRule> rolePermRules = this.jdbcEnhance
.selector()
.SELECT("URL,GROUP_CONCAT(T.ROLE_ID ORDER BY R.URL) NEED_ROLES")
.FROM("T_ROLE_RESOURCE T")
.JOIN("T_RESOURCE R ON T.RESOURCE_ID = R.ID")
.GROUP_BY("R.URL")
.entityClass(RolePermRule.class)
.list();
return rolePermRules;
}
/**
* HMAC数字签名权限验证规则配置
* 为了展示数据原貌使用了硬编码配置
* 真实场景中可以通过界面配置,比如做一个"接口管理"功能
*/
@Override
public List<RolePermRule> loadHmacRules() {
// 删除操作需要通过HMAC数字摘要认证并且具有"role_admin"角色
RolePermRule hmacRule1 = new RolePermRule();
hmacRule1.setUrl("/hmac_api/delete");
hmacRule1.setNeedRoles("role_admin");
/// 其余操作需要通过HMAC数字摘要认证
RolePermRule hmacRule2 = new RolePermRule();
hmacRule2.setUrl("/hmac_api/**");
List<RolePermRule> hmacRules = Lists.newLinkedList();
hmacRules.add(hmacRule1);
hmacRules.add(hmacRule2);
return hmacRules;
}
/**
* JWT令牌权限验证规则配置
* 为了展示数据原貌使用了硬编码配置
* 真实场景中可以通过界面配置,比如做一个"接口管理"功能
*/
@Override
public List<RolePermRule> loadJwtRules() {
/// 删除操作需要通过JWT令牌认证并且具有"role_admin"角色
RolePermRule jwtRule1 = new RolePermRule();
jwtRule1.setUrl("/jwt_api/delete");
jwtRule1.setNeedRoles("role_admin");
/// 其余操作需要通过JWT令牌认证
RolePermRule jwtRule2 = new RolePermRule();
jwtRule2.setUrl("/jwt_api/**");
List<RolePermRule> jwtRules = Lists.newLinkedList();
jwtRules.add(jwtRule1);
jwtRules.add(jwtRule2);
return jwtRules;
}
/**
* 自定义权限验证规则,如果您熟悉shiro的规则表达式,可自定义规则以便定制更简洁有效的规则
* 如果你扩展了shiro的Filter,通过这个方法为扩展的Filter指定规则
*/
@Override
public List<CustomRule> loadCustomRules() {
return null;
}
}
@Configuration
public class ApplicationConfig{
// 账号数据提供服务
@Autowired
private AccountProviderImpl accountProviderImpl;
// 自定义的加密实现
@Autowired
private MyDESPasswordProvider myDESPasswordProvider;
// 自定义的验证码实现
@Autowired
private MyCaptchaService myCaptchaService;
// 密码输入错误次数超限处理器
@Autowired
private PasswdRetryLimitHandler passwdRetryLimitHandler;
// 鉴权规则数据提供服务
@Autowired
private FilteRulesProviderImpl filteRulesProviderImpl;
@Bean
public ShiroCustomizer shiroCustomizer() {
ShiroCustomizer customizer = new ShiroCustomizer();
// 设置账号数据提供服务
customizer.setShiroAccountProvider(accountProviderImpl);
// 设置加密实现
customizer.setPasswordProvider(myDESPasswordProvider);
// 设置验证码实现
customizer.setCaptchaProvider(myCaptchaService);
// 设置密码输入错误次数超限处理器
customizer.setPasswdRetryLimitListener(passwdRetryLimitHandler);
// 设置鉴权规则数据提供服务
customizer.setShiroFilteRulesProvider(filteRulesProviderImpl);
return customizer;
}
}
通过FilteRulesProvider提供的鉴权规则会缓存在系统中,如果修改了角色和资源的关联关系,则需要刷新鉴权规则。如下:
@Service
public class ResourceService {
/**
* 角色-资源绑定
*/
@Transactional
public void roleResBind(String roleId, String resourceIds){
this.roleResourceMapper.deleteResourceByRole(roleId);
for(String resourceId:CommonUtil.split(resourceIds)){
RoleResourceEntity roleResource = new RoleResourceEntity();
roleResource.setRoleId(roleId);
roleResource.setResourceId(resourceId);
this.roleResourceMapper.insert(roleResource);
}
// 角色对应的资源改变,要刷新动态过滤规则,以便及时应用更新
ShiroUtils.reloadFilterRules();
}
}