spring security全局方法安全保护切入点@EnableGlobalMethodSecurity
一个端口如何从spring security全局方法安全保护切入点@EnableGlobalMethodSecurity,spring,spring-security,Spring,Spring Security,一个端口如何从 <sec:global-method-security secured-annotations="disabled"> <sec:protect-pointcut expression='execution(* x.y.z.end*(..))' access='...' /> ? 这里有一个类似的问题有一个解决办法。安全点信息保存在MethodSecurityMetadataSource实现中(然后由MethodInterceptor使用),因此
<sec:global-method-security secured-annotations="disabled">
<sec:protect-pointcut expression='execution(* x.y.z.end*(..))' access='...' />
?
这里有一个类似的问题有一个解决办法。安全点信息保存在
MethodSecurityMetadataSource
实现中(然后由MethodInterceptor
使用),因此我们必须创建一个额外的MethodSecurityMetadataSource
。正如spring论坛帖子中提到的,xml切入点配置保存在MapBasedMethodSecurityMetadataSource
中,并由ProtectPointcutPostProcessor
处理。我们还需要一个ProtectPointcutPostProcessor
的实例。不幸的是,这个类是最终的,包是私有的,因此有两个选项:
@Bean
public Map<String, List<ConfigAttribute>> protectPointcutMap() {
Map<String, List<ConfigAttribute>> map = new HashMap<>();
// all the necessary rules go here
map.put("execution(* your.package.service.*Service.*(..))", SecurityConfig.createList("ROLE_A", "ROLE_B"));
return map;
}
@Bean
public MethodSecurityMetadataSource mappedMethodSecurityMetadataSource() {
// the key is not to provide the above map here. this class will be populated later by ProtectPointcutPostProcessor
return new MapBasedMethodSecurityMetadataSource();
}
// it's either the original spring bean created with reflection or your own copy of it
@Bean
public ProtectPointcutPostProcessor pointcutProcessor() {
ProtectPointcutPostProcessor pointcutProcessor = new ProtectPointcutPostProcessor((MapBasedMethodSecurityMetadataSource) mappedMethodSecurityMetadataSource());
pointcutProcessor.setPointcutMap(protectPointcutMap());
return pointcutProcessor;
}
它将把它放在列表的第一位,但这可能会导致一些问题
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return mappedMethodSecurityMetadataSource();
}
@Override
public MethodSecurityMetadataSource methodSecurityMetadataSource() {
DelegatingMethodSecurityMetadataSource metadataSource = (DelegatingMethodSecurityMetadataSource) super.methodSecurityMetadataSource();
metadataSource.getMethodSecurityMetadataSources().add(mappedMethodSecurityMetadataSource());
return metadataSource;
}
@Secured
或任何其他注释),那么您可以覆盖相同的方法,只是使用不同的内容
@Override
public MethodSecurityMetadataSource methodSecurityMetadataSource() {
return mappedMethodSecurityMetadataSource();
}
就这样!我希望它会有所帮助,因为我遵循了@marhewa注释,并且能够通过定义以下bean来使用类的Spring版本
ProtectPointcutPostProcessor
/**
* Needed to use reflection because I couldn't find a way to instantiate a
* ProtectPointcutPostProcessor via a BeanFactory or ApplicationContext. This bean will process
* the AspectJ pointcut defined in the map; check all beans created by Spring; store the matches
* in the MapBasedMethodSecurityMetadataSource bean so Spring can use it during its checks
*
* @return
* @throws Exception
*/
@Bean(name = "protectPointcutPostProcessor")
Object protectPointcutPostProcessor() throws Exception {
Class<?> clazz =
Class.forName("org.springframework.security.config.method.ProtectPointcutPostProcessor");
Constructor<?> declaredConstructor =
clazz.getDeclaredConstructor(MapBasedMethodSecurityMetadataSource.class);
declaredConstructor.setAccessible(true);
Object instance = declaredConstructor.newInstance(pointcutMethodMetadataSource());
Method setPointcutMap = instance.getClass().getMethod("setPointcutMap", Map.class);
setPointcutMap.setAccessible(true);
setPointcutMap.invoke(instance, pointcuts());
return instance;
}
/**
*需要使用反射,因为我找不到实例化
*通过BeanFactory或ApplicationContext保护PointCutPostProcessor。这个bean将处理
*地图中定义的AspectJ切入点;检查Spring创建的所有bean;储存火柴
*在MapbasedMethodSecurityMetadataSourcebean中,这样Spring就可以在其检查期间使用它
*
*@返回
*@抛出异常
*/
@Bean(name=“protectPointcutPostProcessor”)
对象protectPointcutPostProcessor()引发异常{
课堂讨论=
forName(“org.springframework.security.config.method.ProtectPointcutPostProcessor”);
构造函数声明构造函数=
getDeclaredConstructor(MapBasedMethodSecurityMetadataSource.class);
declaredConstructor.setAccessible(true);
对象实例=declaredConstructor.newInstance(pointcutMethodMetadataSource());
方法setPointcutMap=instance.getClass().getMethod(“setPointcutMap”,Map.class);
setPointcutMap.setAccessible(真);
调用(实例,pointcuts());
返回实例;
}
这样我就不需要复制这个Spring类的代码
干杯
/**
* Needed to use reflection because I couldn't find a way to instantiate a
* ProtectPointcutPostProcessor via a BeanFactory or ApplicationContext. This bean will process
* the AspectJ pointcut defined in the map; check all beans created by Spring; store the matches
* in the MapBasedMethodSecurityMetadataSource bean so Spring can use it during its checks
*
* @return
* @throws Exception
*/
@Bean(name = "protectPointcutPostProcessor")
Object protectPointcutPostProcessor() throws Exception {
Class<?> clazz =
Class.forName("org.springframework.security.config.method.ProtectPointcutPostProcessor");
Constructor<?> declaredConstructor =
clazz.getDeclaredConstructor(MapBasedMethodSecurityMetadataSource.class);
declaredConstructor.setAccessible(true);
Object instance = declaredConstructor.newInstance(pointcutMethodMetadataSource());
Method setPointcutMap = instance.getClass().getMethod("setPointcutMap", Map.class);
setPointcutMap.setAccessible(true);
setPointcutMap.invoke(instance, pointcuts());
return instance;
}