几点感受: shiro等安全框架,非常复杂,组件太多,继承太复杂。老外写的框架都是这个鸟样。
只看本文的结论,很简单,但在找到答案之前,很复杂。
走了点弯路,shiro初始化比较早,据说在其它bean之前。不细说,大概记下。
配置属性:
# when only true,ignore shiro permission control
devMode: true
// 通用注释掉 注解的方式可以忽略权限,但非常麻烦
// @Import(ShiroConfig.class)
public class Application {}
初始化属性
@Component
@Slf4j
public class ConfigCommandLineRunner implements CommandLineRunner{
@Autowired
private Environment env;
public void initProperties() {
String devMode = env.getProperty("devMode");
if (StringUtils.equals(devMode, "true")) {
DevConfig.devMode = true;
log.info("ConfigCommandLineRunner run devMode is true");
}
}
@Override
public void run(String... arg0) throws Exception {
initProperties();
}
}
扩展Shiro的权限控制组件
/**
* 开发阶段,放过方法注解的拦截。提高开发效率.精益求精,快中求快。
*
*/
public class MyAuthorizationAttributeSourceAdvisor extends AuthorizationAttributeSourceAdvisor{
private static final long serialVersionUID = 1L;
@Override
public boolean matches(Method method, Class targetClass) {
if(DevConfig.devMode){
return false;
}
return super.matches(method, targetClass);
}
}
@Slf4j
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
log.info("MyFormAuthenticationFilter.isAccessAllowed()");
if(DevConfig.devMode){
return true;
}
return super.isAccessAllowed(request, response, mappedValue);
}
}
Shiro配置
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor aasa = new MyAuthorizationAttributeSourceAdvisor();
aasa.setSecurityManager(getDefaultWebSecurityManager());
return aasa;
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager, CasFilter casFilter) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, Filter> filters = new HashMap<>();
//自定义filter.
MyFormAuthenticationFilter formAuthenticationFilter = new MyFormAuthenticationFilter();
//重新定义formAuthenticationFilter
filters.put("authc", formAuthenticationFilter);
//交给spring shiroFilter管理
shiroFilterFactoryBean.setFilters(filters);
loadShiroFilterChain(shiroFilterFactoryBean);
return shiroFilterFactoryBean;
}
忽略数据权限,大概例子
/**
* 区域权限
*/
protected List<Integer> getAllAllowRegionId() {
Optional<Object> casJson = getSessionInfo("allowRegionId");
String allowRegionId = (String) casJson.orElse("");
if(DevConfig.devMode){
allowRegionId="0,4,5,6,7,9,12,14";
}
List<Integer> allowRegionIdList = JavaKit.splitAsIntList(allowRegionId, ",");
return allowRegionIdList;
}
/**
* 填充测试标记公司.没有测试权限时,设置isTest为0
*/
protected void fillIsTest(PermissionVo permissionVo) {
if(DevConfig.devMode){
log.info("DevMode true,ignore fillIsTest");
return;
}
boolean hasTestPermission=hasTestPermission();
if(!hasTestPermission){
permissionVo.setIsTest(0);
}
}