Support both JWT and Opaque token configuration for resource server
Closes gh-19426
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,8 +19,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
@@ -49,26 +47,6 @@ public class OAuth2ResourceServerProperties {
|
|||||||
return this.opaqueToken;
|
return this.opaqueToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void validate() {
|
|
||||||
if (this.getOpaquetoken().getIntrospectionUri() != null) {
|
|
||||||
if (this.getJwt().getJwkSetUri() != null) {
|
|
||||||
handleError("jwt.jwk-set-uri");
|
|
||||||
}
|
|
||||||
if (this.getJwt().getIssuerUri() != null) {
|
|
||||||
handleError("jwt.issuer-uri");
|
|
||||||
}
|
|
||||||
if (this.getJwt().getPublicKeyLocation() != null) {
|
|
||||||
handleError("jwt.public-key-location");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleError(String property) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Only one of " + property + " and opaquetoken.introspection-uri should be configured.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Jwt {
|
public static class Jwt {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -26,9 +26,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
|
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
|
||||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
|
||||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
|
||||||
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EnableAutoConfiguration Auto-configuration} for Reactive OAuth2 resource server
|
* {@link EnableAutoConfiguration Auto-configuration} for Reactive OAuth2 resource server
|
||||||
@@ -42,22 +39,8 @@ import org.springframework.security.oauth2.server.resource.introspection.Reactiv
|
|||||||
@EnableConfigurationProperties(OAuth2ResourceServerProperties.class)
|
@EnableConfigurationProperties(OAuth2ResourceServerProperties.class)
|
||||||
@ConditionalOnClass({ EnableWebFluxSecurity.class })
|
@ConditionalOnClass({ EnableWebFluxSecurity.class })
|
||||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||||
|
@Import({ ReactiveOAuth2ResourceServerConfiguration.JwtConfiguration.class,
|
||||||
|
ReactiveOAuth2ResourceServerConfiguration.OpaqueTokenConfiguration.class })
|
||||||
public class ReactiveOAuth2ResourceServerAutoConfiguration {
|
public class ReactiveOAuth2ResourceServerAutoConfiguration {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
@ConditionalOnClass({ BearerTokenAuthenticationToken.class, ReactiveJwtDecoder.class })
|
|
||||||
@Import({ ReactiveOAuth2ResourceServerJwkConfiguration.JwtConfiguration.class,
|
|
||||||
ReactiveOAuth2ResourceServerJwkConfiguration.WebSecurityConfiguration.class })
|
|
||||||
static class JwtConfiguration {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
@ConditionalOnClass({ BearerTokenAuthenticationToken.class, ReactiveOpaqueTokenIntrospector.class })
|
|
||||||
@Import({ ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.OpaqueTokenIntrospectionClientConfiguration.class,
|
|
||||||
ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.WebSecurityConfiguration.class })
|
|
||||||
static class OpaqueTokenConfiguration {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2020 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||||
|
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
||||||
|
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration classes for OAuth2 Resource Server These should be {@code @Import} in a
|
||||||
|
* regular auto-configuration class to guarantee their order of execution.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
class ReactiveOAuth2ResourceServerConfiguration {
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@ConditionalOnClass({ BearerTokenAuthenticationToken.class, ReactiveJwtDecoder.class })
|
||||||
|
@Import({ ReactiveOAuth2ResourceServerJwkConfiguration.JwtConfiguration.class,
|
||||||
|
ReactiveOAuth2ResourceServerJwkConfiguration.WebSecurityConfiguration.class })
|
||||||
|
static class JwtConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@ConditionalOnClass({ BearerTokenAuthenticationToken.class, ReactiveOpaqueTokenIntrospector.class })
|
||||||
|
@Import({ ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.OpaqueTokenIntrospectionClientConfiguration.class,
|
||||||
|
ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.WebSecurityConfiguration.class })
|
||||||
|
static class OpaqueTokenConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,7 +17,6 @@ package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet;
|
|||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
|
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
|
||||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||||
@@ -25,10 +24,6 @@ import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServic
|
|||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
|
||||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
|
||||||
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EnableAutoConfiguration Auto-configuration} for OAuth2 resource server support.
|
* {@link EnableAutoConfiguration Auto-configuration} for OAuth2 resource server support.
|
||||||
@@ -40,23 +35,8 @@ import org.springframework.security.oauth2.server.resource.introspection.OpaqueT
|
|||||||
@AutoConfigureBefore({ SecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class })
|
@AutoConfigureBefore({ SecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class })
|
||||||
@EnableConfigurationProperties(OAuth2ResourceServerProperties.class)
|
@EnableConfigurationProperties(OAuth2ResourceServerProperties.class)
|
||||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||||
|
@Import({ Oauth2ResourceServerConfiguration.JwtConfiguration.class,
|
||||||
|
Oauth2ResourceServerConfiguration.OpaqueTokenConfiguration.class })
|
||||||
public class OAuth2ResourceServerAutoConfiguration {
|
public class OAuth2ResourceServerAutoConfiguration {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
@ConditionalOnClass({ JwtAuthenticationToken.class, JwtDecoder.class })
|
|
||||||
@Import({ OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration.class,
|
|
||||||
OAuth2ResourceServerJwtConfiguration.OAuth2WebSecurityConfigurerAdapter.class })
|
|
||||||
static class JwtConfiguration {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
@ConditionalOnClass({ BearerTokenAuthenticationToken.class, OpaqueTokenIntrospector.class })
|
|
||||||
@Import({ OAuth2ResourceServerOpaqueTokenConfiguration.OpaqueTokenIntrospectionClientConfiguration.class,
|
|
||||||
OAuth2ResourceServerOpaqueTokenConfiguration.OAuth2WebSecurityConfigurerAdapter.class })
|
|
||||||
static class OpaqueTokenConfiguration {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2020 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||||
|
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||||
|
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration classes for OAuth2 Resource Server
|
||||||
|
* These should be {@code @Import} in a regular auto-configuration class to guarantee
|
||||||
|
* their order of execution.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
class Oauth2ResourceServerConfiguration {
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@ConditionalOnClass({ JwtAuthenticationToken.class, JwtDecoder.class })
|
||||||
|
@Import({ OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration.class,
|
||||||
|
OAuth2ResourceServerJwtConfiguration.OAuth2WebSecurityConfigurerAdapter.class })
|
||||||
|
static class JwtConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@ConditionalOnClass({ BearerTokenAuthenticationToken.class, OpaqueTokenIntrospector.class })
|
||||||
|
@Import({ OAuth2ResourceServerOpaqueTokenConfiguration.OpaqueTokenIntrospectionClientConfiguration.class,
|
||||||
|
OAuth2ResourceServerOpaqueTokenConfiguration.OAuth2WebSecurityConfigurerAdapter.class })
|
||||||
|
static class OpaqueTokenConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -288,6 +288,20 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void autoConfigurationWhenJwkSetUriAndIntrospectionUriAvailable() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com",
|
||||||
|
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
||||||
|
"spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id",
|
||||||
|
"spring.security.oauth2.resourceserver.opaquetoken.client-secret=my-client-secret")
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(ReactiveOpaqueTokenIntrospector.class);
|
||||||
|
assertThat(context).hasSingleBean(ReactiveJwtDecoder.class);
|
||||||
|
assertFilterConfiguredWithJwtAuthenticationManager(context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void opaqueTokenIntrospectorIsConditionalOnMissingBean() {
|
void opaqueTokenIntrospectorIsConditionalOnMissingBean() {
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
@@ -320,36 +334,6 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests {
|
|||||||
.run((context) -> assertThat(context).doesNotHaveBean(ReactiveOpaqueTokenIntrospector.class));
|
.run((context) -> assertThat(context).doesNotHaveBean(ReactiveOpaqueTokenIntrospector.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void autoConfigurationWhenBothJwkSetUriAndTokenIntrospectionUriSetShouldFail() {
|
|
||||||
this.contextRunner
|
|
||||||
.withPropertyValues(
|
|
||||||
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
|
||||||
"spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com")
|
|
||||||
.run((context) -> assertThat(context).hasFailed().getFailure().hasMessageContaining(
|
|
||||||
"Only one of jwt.jwk-set-uri and opaquetoken.introspection-uri should be configured."));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void autoConfigurationWhenBothJwtIssuerUriAndTokenIntrospectionUriSetShouldFail() {
|
|
||||||
this.contextRunner
|
|
||||||
.withPropertyValues(
|
|
||||||
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
|
||||||
"spring.security.oauth2.resourceserver.jwt.issuer-uri=https://jwk-oidc-issuer-location.com")
|
|
||||||
.run((context) -> assertThat(context).hasFailed().getFailure().hasMessageContaining(
|
|
||||||
"Only one of jwt.issuer-uri and opaquetoken.introspection-uri should be configured."));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void autoConfigurationWhenBothJwtKeyLocationAndTokenIntrospectionUriSetShouldFail() {
|
|
||||||
this.contextRunner
|
|
||||||
.withPropertyValues(
|
|
||||||
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
|
||||||
"spring.security.oauth2.resourceserver.jwt.public-key-location=classpath:public-key-location")
|
|
||||||
.run((context) -> assertThat(context).hasFailed().getFailure().hasMessageContaining(
|
|
||||||
"Only one of jwt.public-key-location and opaquetoken.introspection-uri should be configured."));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test
|
||||||
void autoConfigurationShouldConfigureResourceServerUsingJwkSetUriAndIssuerUri() throws Exception {
|
void autoConfigurationShouldConfigureResourceServerUsingJwkSetUriAndIssuerUri() throws Exception {
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import org.springframework.security.oauth2.jwt.Jwt;
|
|||||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||||
import org.springframework.security.oauth2.jwt.JwtIssuerValidator;
|
import org.springframework.security.oauth2.jwt.JwtIssuerValidator;
|
||||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||||
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
|
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
|
||||||
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter;
|
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter;
|
||||||
@@ -273,6 +274,22 @@ class OAuth2ResourceServerAutoConfigurationTests {
|
|||||||
.run((context) -> assertThat(getBearerTokenFilter(context)).isNull());
|
.run((context) -> assertThat(getBearerTokenFilter(context)).isNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void autoConfigurationWhenJwkSetUriAndIntrospectionUriAvailable() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com",
|
||||||
|
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
||||||
|
"spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id",
|
||||||
|
"spring.security.oauth2.resourceserver.opaquetoken.client-secret=my-client-secret")
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(OpaqueTokenIntrospector.class);
|
||||||
|
assertThat(context).hasSingleBean(JwtDecoder.class);
|
||||||
|
assertThat(getBearerTokenFilter(context))
|
||||||
|
.extracting("authenticationManagerResolver.arg$1.providers").asList()
|
||||||
|
.hasAtLeastOneElementOfType(JwtAuthenticationProvider.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void autoConfigurationWhenIntrospectionUriAvailableShouldConfigureIntrospectionClient() {
|
void autoConfigurationWhenIntrospectionUriAvailableShouldConfigureIntrospectionClient() {
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
@@ -305,36 +322,6 @@ class OAuth2ResourceServerAutoConfigurationTests {
|
|||||||
.run((context) -> assertThat(context).doesNotHaveBean(OpaqueTokenIntrospector.class));
|
.run((context) -> assertThat(context).doesNotHaveBean(OpaqueTokenIntrospector.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void autoConfigurationWhenBothJwkSetUriAndTokenIntrospectionUriSetShouldFail() {
|
|
||||||
this.contextRunner
|
|
||||||
.withPropertyValues(
|
|
||||||
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
|
||||||
"spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com")
|
|
||||||
.run((context) -> assertThat(context).hasFailed().getFailure().hasMessageContaining(
|
|
||||||
"Only one of jwt.jwk-set-uri and opaquetoken.introspection-uri should be configured."));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void autoConfigurationWhenBothJwtIssuerUriAndTokenIntrospectionUriSetShouldFail() {
|
|
||||||
this.contextRunner
|
|
||||||
.withPropertyValues(
|
|
||||||
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
|
||||||
"spring.security.oauth2.resourceserver.jwt.issuer-uri=https://jwk-oidc-issuer-location.com")
|
|
||||||
.run((context) -> assertThat(context).hasFailed().getFailure().hasMessageContaining(
|
|
||||||
"Only one of jwt.issuer-uri and opaquetoken.introspection-uri should be configured."));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void autoConfigurationWhenBothJwtKeyLocationAndTokenIntrospectionUriSetShouldFail() {
|
|
||||||
this.contextRunner
|
|
||||||
.withPropertyValues(
|
|
||||||
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
|
||||||
"spring.security.oauth2.resourceserver.jwt.public-key-location=classpath:public-key-location")
|
|
||||||
.run((context) -> assertThat(context).hasFailed().getFailure().hasMessageContaining(
|
|
||||||
"Only one of jwt.public-key-location and opaquetoken.introspection-uri should be configured."));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test
|
||||||
void autoConfigurationShouldConfigureResourceServerUsingJwkSetUriAndIssuerUri() throws Exception {
|
void autoConfigurationShouldConfigureResourceServerUsingJwkSetUriAndIssuerUri() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user