Polish oauth2ResourceServer() Error Messaging

Fixes: gh-6876
This commit is contained in:
Josh Cummings 2019-05-22 16:54:43 -06:00
parent 1fc5b27fa2
commit de672e3ae9
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
4 changed files with 93 additions and 24 deletions

View File

@ -232,19 +232,7 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
BearerTokenResolver bearerTokenResolver = getBearerTokenResolver();
this.requestMatcher.setBearerTokenResolver(bearerTokenResolver);
if (this.jwtConfigurer != null && this.opaqueTokenConfigurer != null) {
throw new IllegalStateException("Spring Security only supports JWTs or Opaque Tokens, not both at the " +
"same time");
}
if (this.jwtConfigurer == null && this.opaqueTokenConfigurer == null &&
this.authenticationManagerResolver == null ) {
throw new IllegalStateException("Jwt and Opaque Token are the only supported formats for bearer tokens " +
"in Spring Security and neither was found. Make sure to configure JWT " +
"via http.oauth2ResourceServer().jwt() or Opaque Tokens via " +
"http.oauth2ResourceServer().opaque().");
}
validateConfiguration();
AuthenticationManagerResolver resolver = this.authenticationManagerResolver;
if (resolver == null) {
@ -260,6 +248,27 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
http.addFilter(filter);
}
private void validateConfiguration() {
if (this.authenticationManagerResolver == null) {
if (this.jwtConfigurer == null && this.opaqueTokenConfigurer == null) {
throw new IllegalStateException("Jwt and Opaque Token are the only supported formats for bearer tokens " +
"in Spring Security and neither was found. Make sure to configure JWT " +
"via http.oauth2ResourceServer().jwt() or Opaque Tokens via " +
"http.oauth2ResourceServer().opaqueToken().");
}
if (this.jwtConfigurer != null && this.opaqueTokenConfigurer != null) {
throw new IllegalStateException("Spring Security only supports JWTs or Opaque Tokens, not both at the " +
"same time.");
}
} else {
if (this.jwtConfigurer != null || this.opaqueTokenConfigurer != null) {
throw new IllegalStateException("If an authenticationManagerResolver() is configured, then it takes " +
"precedence over any jwt() or opaqueToken() configuration.");
}
}
}
public class JwtConfigurer {
private final ApplicationContext context;

View File

@ -1622,17 +1622,7 @@ public class ServerHttpSecurity {
registerDefaultAuthenticationEntryPoint(http);
registerDefaultCsrfOverride(http);
if (this.jwt != null && this.opaqueToken != null) {
throw new IllegalStateException("Spring Security only supports JWTs or Opaque Tokens, not both at the " +
"same time");
}
if (this.jwt == null && this.opaqueToken == null && this.authenticationManagerResolver == null) {
throw new IllegalStateException("Jwt and Opaque Token are the only supported formats for bearer tokens " +
"in Spring Security and neither was found. Make sure to configure JWT " +
"via http.oauth2ResourceServer().jwt() or Opaque Tokens via " +
"http.oauth2ResourceServer().opaqueToken().");
}
validateConfiguration();
if (this.authenticationManagerResolver != null) {
AuthenticationWebFilter oauth2 = new AuthenticationWebFilter(this.authenticationManagerResolver);
@ -1646,6 +1636,27 @@ public class ServerHttpSecurity {
}
}
private void validateConfiguration() {
if (this.authenticationManagerResolver == null) {
if (this.jwt == null && this.opaqueToken == null) {
throw new IllegalStateException("Jwt and Opaque Token are the only supported formats for bearer tokens " +
"in Spring Security and neither was found. Make sure to configure JWT " +
"via http.oauth2ResourceServer().jwt() or Opaque Tokens via " +
"http.oauth2ResourceServer().opaqueToken().");
}
if (this.jwt != null && this.opaqueToken != null) {
throw new IllegalStateException("Spring Security only supports JWTs or Opaque Tokens, not both at the " +
"same time.");
}
} else {
if (this.jwt != null || this.opaqueToken != null) {
throw new IllegalStateException("If an authenticationManagerResolver() is configured, then it takes " +
"precedence over any jwt() or opaqueToken() configuration.");
}
}
}
private void registerDefaultAccessDeniedHandler(ServerHttpSecurity http) {
if ( http.exceptionHandling != null ) {
http.defaultAccessDeniedHandlers.add(

View File

@ -65,6 +65,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationManagerResolver;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
@ -1358,6 +1359,13 @@ public class OAuth2ResourceServerConfigurerTests {
.hasMessageContaining("Spring Security only supports JWTs or Opaque Tokens");
}
@Test
public void configureWhenUsingBothAuthenticationManagerResolverAndOpaqueThenWiringException() {
assertThatCode(() -> this.spring.register(AuthenticationManagerResolverPlusOtherConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("authenticationManagerResolver");
}
// -- support
@EnableWebSecurity
@ -2064,6 +2072,21 @@ public class OAuth2ResourceServerConfigurerTests {
}
}
@EnableWebSecurity
static class AuthenticationManagerResolverPlusOtherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.authenticationManagerResolver(mock(AuthenticationManagerResolver.class))
.opaqueToken();
}
}
@Configuration
static class JwtDecoderConfig {
@Bean

View File

@ -41,6 +41,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
@ -457,6 +458,13 @@ public class OAuth2ResourceServerSpecTests {
.expectStatus().isOk();
}
@Test
public void configureWhenUsingBothAuthenticationManagerResolverAndOpaqueThenWiringException() {
assertThatCode(() -> this.spring.register(AuthenticationManagerResolverPlusOtherConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("authenticationManagerResolver");
}
@EnableWebFlux
@EnableWebFluxSecurity
static class PublicKeyConfig {
@ -849,6 +857,24 @@ public class OAuth2ResourceServerSpecTests {
}
}
@EnableWebFlux
@EnableWebFluxSecurity
static class AuthenticationManagerResolverPlusOtherConfig {
@Bean
SecurityWebFilterChain springSecurity(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.authenticationManagerResolver(mock(ReactiveAuthenticationManagerResolver.class))
.opaqueToken();
return http.build();
}
}
@RestController
static class RootController {
@GetMapping