Spring Security和EnableGlobalMethodSecurity

时间:2013-12-11 12:45:32

标签: spring spring-security

我正在尝试使用带有注释的Spring Security java配置。基本上我想使用注释方法和静态配置的组合。

http
    .authorizeRequests()
    .anyRequest().authenticated()

并且

@Controller
@RequestMapping({"/version", "/*/version"})
@PermitAll
public class VersionController {
// Implementation
}

我很少希望@PermitAll必须优先于其他选民。在这种情况下可以使用@EnableGlobalMethodSecurity(jsr250Enabled = true)吗?

2 个答案:

答案 0 :(得分:0)

据我所知,使用方法安全性无法实现目标,因为请求处理管道如下所示:

  1. Spring Security应用Web安全规则
  2. DispatcherServlet选择hanlder方法
  3. 方法安全性应用于处理程序方法,如果它具有安全注释
  4. 但是,您可以尝试使用不同的方法(未经测试)来实现它:

    • 按照here
    • 所述提取所有处理程序方法的元数据
    • 用它来配置Spring Secuirty
      例如,为包含自定义RequestMappingInfo注释的所有方法选择@PermitAll,并创建一个自定义RequestMatcher,以便对这些方法的请求返回true。然后配置Spring Security以允许每个人访问与所述匹配器匹配的URL。

答案 1 :(得分:0)

我已经改变了我的观点,并开始考虑另一种解决方案。如果我可以在Spring安全性开始之前知道我的控制器,我可以通过处理它来配置它。基本上我创建了一个处理器,我的实现的简化版本是:

@Component
public class PermitAllProcessor {

   private static final Logger logger = LoggerFactory.getLogger(PermitAllProcessor.class);

   @Autowired
   AbstractHandlerMethodMapping abstractHandlerMethodMapping;


   public String[] process() {
      Map<RequestMappingInfo, HandlerMethod> handlerMethods = abstractHandlerMethodMapping.getHandlerMethods();
      ArrayList<String> urls = Lists.newArrayList();
      for(Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
         PermitAll annotation = getPermitAll(entry.getValue());
         if(annotation != null) {
            Set<String> patterns = entry.getKey().getPatternsCondition().getPatterns();
            urls.addAll(patterns);
         }
      }
      logger.info("Permitted urls as follows: {}",
                    StringUtils.collectionToDelimitedString(urls, ",", "[", "]"));
      return urls.toArray(new String[urls.size()]);
   }

   private PermitAll getPermitAll(HandlerMethod value) {
      PermitAll annotation = value.getMethodAnnotation(PermitAll.class);
      if(annotation == null){
         annotation = value.getBeanType().getAnnotation(PermitAll.class);
      }
      return annotation;
   }
}

基本上

 .authorizeRequests()
    .antMatchers(permitAllProcessor.process()).permitAll()
    .anyRequest().authenticated();