我有一个启用了Spring Security的Spring Resource Server。在Resource Server中,我正在扩展ResourceServerConfigurerAdaptor,如下所示。
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.anonymous().disable().requestMatcher(new OAuthRequestedMatcher()).authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/admin/**").hasAnyRole("ADMIN")
.anyRequest().authenticated();
}
private static class OAuthRequestedMatcher implements RequestMatcher {
public boolean matches(HttpServletRequest request) {
String auth = request.getHeader("Authorization");
boolean haveOauth2Token = (auth != null) && auth.toLowerCase().startsWith("bearer");
boolean haveAccessToken = request.getParameter("access_token") != null;
return haveOauth2Token || haveAccessToken;
}
}
}
在这里,我希望只有ADMIN Role可以访问/api/admin/**
。
到目前为止一切正常。
但是现在我尝试使用@PreAuthorize
方法级别注释在方法级别覆盖此行为。
以下是RestController
@RestController
@RequestMapping("/api/admin/event")
public class ShunyaEventResource {
@Autowired
private ShunyaEventService eventService;
@PreAuthorize("hasRole('ADMIN') or #oauth2.hasScope('write')")
@PostMapping
public void createEvent(@RequestBody ShunyaEvent event, Principal user) {
eventService.create(event);
}
}
因此,我希望/api/admin/event
也可以访问#oauth2 write
范围。但这不起作用,除非我完全从antmatcher中删除/api/admin/**
或者在antmatcher中添加#oauth2.hasScope('write')。
我已经定义了以下配置
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
这里我的问题是为什么方法级安全性不适用于ResourceServerConfigurerAdapter已涵盖的端点?当MethodLevel Security(使用PreAuthorize)和HttpSecurity antMatcher涵盖相同端点时,安全过滤器的优先级是什么?
真的很感激任何帮助。