Java Spring安全性:如果缺少@PreAuthorize注释,则拒绝对控制器方法的访问
我有一个web应用程序配置为以标准方式使用SpringSecurity3.2 我正在使用Java Spring安全性:如果缺少@PreAuthorize注释,则拒绝对控制器方法的访问,java,spring,spring-security,Java,Spring,Spring Security,我有一个web应用程序配置为以标准方式使用SpringSecurity3.2 我正在使用@PreAuthorize注释来保护Controllers方法。 现在,我想拒绝对每个控制器方法的访问,除非它用@PreAuthorize注释 我尝试了以下方法: 超级控制器 每个控制器都从一个超级控制器扩展而来,超级控制器的注释为:@preautoize(“denyAll”)。这种方法似乎不起作用,因为忽略了控制器的方法注释。一切都是禁止的 @PreAutorize("denyAll") public c
@PreAuthorize
注释来保护Controllers方法。
现在,我想拒绝对每个控制器方法的访问,除非它用@PreAuthorize
注释
我尝试了以下方法:
超级控制器
每个控制器都从一个超级控制器扩展而来,超级控制器的注释为:@preautoize(“denyAll”)
。这种方法似乎不起作用,因为忽略了控制器的方法注释。一切都是禁止的
@PreAutorize("denyAll")
public class SuperController {
}
public class MyController extends SuperController {
@PreAuthorize("hasRole('SUPERHERO')")
@RequestMapping(value = URL_PREFIX + "Add.do", method = RequestMethod.GET)
public String doStuff(Model model) {
...
}
}
aop
在全局方法安全标记中使用切入点表达式
<global-method-security pre-post-annotations="enabled">
<protect-pointcut expression="execution(* com.acme.*Controller.*(..))" access="denyAll" />
</global-method-security>
这种方法也失败了:没有注释的控制器方法仍然可以访问。我在这里回答我自己的问题 我用一种新方法解决了这个问题 我不确定这是实现这个结果的最常用的方式,但对我来说已经足够好了
public class MvcPreAuthorizeAnnotationCheckerInterceptor extends HandlerInterceptorAdapter {
final HandlerMethod hm;
if (handler instanceof HandlerMethod) {
hm = (HandlerMethod) handler;
PreAuthorize annotation = hm.getMethodAnnotation(PreAuthorize.class);
if (annotation == null) {
// check if the class is annotated...
annotation = hm.getMethod().getDeclaringClass().getAnnotation(PreAuthorize.class);
if (annotation == null) {
// add logging
// or send a NON AUTHORIZED
response.sendRedirect(request.getContextPath());
}
}
return true;
}
}
在Spring配置中:
<mvc:interceptors>
<beans:ref bean="mvcPreAuthorizeAnnotationCheckerInterceptor"/>
</mvc:interceptors>
<beans:bean id="mvcPreAuthorizeAnnotationCheckerInterceptor" class="com.acme.MvcPreAuthorizeAnnotationCheckerInterceptor"/>
我提出了一种类似的方法,但它并不是针对每个请求都执行,而是扩展了该方法的
ConfigAttribute
:
一个小缺点可能是它不允许简单的日志记录,或者其他任何好处是它遵循与其他不允许的端点相同的拒绝行为
证券配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return new CustomPermissionAllowedMethodSecurityMetadataSource();
}
}
元数据源:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return new CustomPermissionAllowedMethodSecurityMetadataSource();
}
}
公共类CustomPermissionAllowedMethodSecurityMetadataSource扩展了AbstractFallbackMethodSecurityMetadataSource{
@凌驾
受保护的集合findAttributes(类别clazz){
返回null;
}
@凌驾
受保护的集合findAttributes(方法,类targetClass){
Annotation[]annotations=AnnotationUtils.getAnnotations(方法);
列表属性=新的ArrayList();
//如果类本身被注释为@Controller,那么默认情况下我们应该拒绝对每个方法的访问
if(AnnotationUtils.findAnnotation(targetClass,Controller.class)!=null){
添加(拒绝所有属性);
}
if(注释!=null){
对于(注释a:注释){
//但如果该方法至少具有预授权或后授权注释,则不会
if(预授权的实例| |后授权的实例){
返回null;
}
}
}
返回属性;
}
@凌驾
公共集合getAllConfigAttributes(){
返回null;
}
}
我还写了一篇关于这一点的小文章,并提供了一些进一步的背景: