我正在尝试通过OAuth或基本身份验证来保护一组资源(/ admin / **)。我已经成功地单独实现了这两个(使用@Order的两个差异WebSecurityAdapters)或一起实现了(一个WebSecurityAdapter)。但是,我需要使用或。
我目前的策略是对/ admin / **的POST使用基本身份验证,而对相同URL的GET使用OAuth。这可行吗?还是有另一种方法可以做到这一点?
或者是否有办法使对/ admin / **的所有请求都需要OAuth,除非有人通过基本身份验证进行了验证-并且有一种方法可以对将正确填充SecurityContext的其他URL进行基本身份验证,因此如果执行了基本身份验证,那么对/ admin / **的访问是否也不会进行OAuth?
OAuth或基本身份验证的当前实现(取决于Order(1)是哪一个):
@Configuration
@Order(2)
public class BasicAuth extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().sameOrigin().and().cors().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and().httpBasic().and().authorizeRequests()
.antMatchers("/**/*.{js,html,css}", "/", "/api/user", "/static/css/**/*", "/static/css/*", "/static/js/*", "/static/js/**/*").permitAll()
.anyRequest().authenticated();
}
}
@EnableWebSecurity(debug = true)
@Configuration
@Order(1)
public class OAuth extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(this.oauthConsumerContextFilter(), SwitchUserFilter.class);
http.addFilterAfter(this.oauthConsumerProcessingFilter(), OAuthConsumerContextFilter.class);
}
// IMPORTANT: this must not be a Bean
OAuthConsumerContextFilter oauthConsumerContextFilter() {
OAuthConsumerContextFilter filter = new OAuthConsumerContextFilter();
filter.setConsumerSupport(this.consumerSupport());
return filter;
}
// IMPORTANT: this must not be a Bean
OAuthConsumerProcessingFilter oauthConsumerProcessingFilter() {
OAuthConsumerProcessingFilter filter = new OAuthConsumerProcessingFilter();
filter.setProtectedResourceDetailsService(this.prds());
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> map = new LinkedHashMap<>();
// one entry per oauth:url element in xml
map.put(
// 1st arg is equivalent of url:pattern in xml
// 2nd arg is equivalent of url:httpMethod in xml
new AntPathRequestMatcher("/admin/**", null),
// arg is equivalent of url:resources in xml
// IMPORTANT: this must match the ids in prds() and prd() below
Collections.singletonList(new SecurityConfig("myResource")));
map.put(
// 1st arg is equivalent of url:pattern in xml
// 2nd arg is equivalent of url:httpMethod in xml
new AntPathRequestMatcher("/auth/setup", null),
// arg is equivalent of url:resources in xml
// IMPORTANT: this must match the ids in prds() and prd() below
Collections.singletonList(new SecurityConfig("myResource")));
filter.setObjectDefinitionSource(new DefaultFilterInvocationSecurityMetadataSource(map));
return filter;
}
@Bean // optional, I re-use it elsewhere, hence the Bean
OAuthConsumerSupport consumerSupport() {
CoreOAuthConsumerSupport consumerSupport = new CoreOAuthConsumerSupport();
consumerSupport.setProtectedResourceDetailsService(prds());
return consumerSupport;
}
@Bean // optional, I re-use it elsewhere, hence the Bean
ProtectedResourceDetailsService prds() {
return (String id) -> {
switch (id) {
// this must match the id in prd() below
case "myResource":
return prd();
}
throw new RuntimeException("Invalid id: " + id);
};
}
ProtectedResourceDetails prd() {
BaseProtectedResourceDetails details = new BaseProtectedResourceDetails();
// this must be present and match the id in prds() and prd() above
details.setId("myResource");
details.setConsumerKey("asdf");
details.setSharedSecret(new SharedConsumerSecretImpl("asdf"));
details.setRequestTokenURL("<url>/oauth-request-token");
details.setUserAuthorizationURL("<url>/oauth-authorize");
details.setAccessTokenURL("<url>/oauth-access-token");
// enable oauth 1.0a
details.setUse10a(true);
// any other service-specific settings
return details;
}
}
答案 0 :(得分:0)
您可以如下定义安全适配器:
@EnableWebSecurity(debug = true)
@Configuration
@Order(1)
public class OAuth extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new AntPathRequestMatcher("/admin/**", HttpMethod.GET.toString()));
http.addFilterAfter(this.oauthConsumerContextFilter(), SwitchUserFilter.class);
http.addFilterAfter(this.oauthConsumerProcessingFilter(), OAuthConsumerContextFilter.class);
}
@Configuration
@Order(2)
public class BasicAuth extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new AntPathRequestMatcher("/admin/**", HttpMethod.POST.toString())).headers().frameOptions().sameOrigin().and().cors().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and().httpBasic().and().authorizeRequests()
.antMatchers("/**/*.{js,html,css}", "/", "/api/user", "/static/css/**/*", "/static/css/*", "/static/js/*", "/static/js/**/*").permitAll()
.anyRequest().authenticated();
}
}
以上配置应允许POST请求使用BASIC Auth,GET请求使用OAUTH。
答案 1 :(得分:0)
您可以定义一个自定义请求匹配器以检查基本身份验证:
public class BasicUrlAntPathRequestMatcher implements RequestMatcher {
private final String pattern;
public BasicUrlAntPathRequestMatcher(String pattern) {
this.pattern = pattern;
}
@Override
public boolean matches(HttpServletRequest request) {
String auth = request.getHeader(HttpHeaders.AUTHORIZATION);
boolean hasBasicToken = (auth != null) && auth.startsWith("Basic");
return !(new AntPathRequestMatcher(this.pattern).matches(request) || hasBasicToken);
}}
在OAuth配置类中,您可以在http配置中添加此行
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new BasicUrlAntPathRequestMatcher("your/basic/login"));
http.addFilterAfter(this.oauthConsumerContextFilter(), SwitchUserFilter.class);
http.addFilterAfter(this.oauthConsumerProcessingFilter(), OAuthConsumerContextFilter.class);
}