1
0
mirror of synced 2026-05-22 21:33:16 +00:00

Merge branch '5.8.x'

This commit is contained in:
Steve Riesenberg
2022-09-13 17:38:10 -05:00
19 changed files with 552 additions and 45 deletions
@@ -44,6 +44,7 @@ import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
import org.springframework.security.oauth2.server.resource.authentication.OpaqueTokenAuthenticationProvider;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.SpringOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
@@ -105,8 +106,8 @@ import org.springframework.web.accept.HeaderContentNegotiationStrategy;
* </ul>
*
* <p>
* When using {@link #opaqueToken(Customizer)}, supply an introspection endpoint and its
* authentication configuration
* When using {@link #opaqueToken(Customizer)}, supply an introspection endpoint with its
* client credentials and an OpaqueTokenAuthenticationConverter
* </p>
*
* <h2>Security Filters</h2>
@@ -136,6 +137,7 @@ import org.springframework.web.accept.HeaderContentNegotiationStrategy;
*
* @author Josh Cummings
* @author Evgeniy Cheban
* @author Jerome Wacongne &lt;ch4mp@c4-soft.com&gt;
* @since 5.1
* @see BearerTokenAuthenticationFilter
* @see JwtAuthenticationProvider
@@ -448,6 +450,8 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
private Supplier<OpaqueTokenIntrospector> introspector;
private OpaqueTokenAuthenticationConverter authenticationConverter;
OpaqueTokenConfigurer(ApplicationContext context) {
this.context = context;
}
@@ -482,6 +486,13 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
return this;
}
public OpaqueTokenConfigurer authenticationConverter(
OpaqueTokenAuthenticationConverter authenticationConverter) {
Assert.notNull(authenticationConverter, "authenticationConverter cannot be null");
this.authenticationConverter = authenticationConverter;
return this;
}
OpaqueTokenIntrospector getIntrospector() {
if (this.introspector != null) {
return this.introspector.get();
@@ -489,12 +500,28 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
return this.context.getBean(OpaqueTokenIntrospector.class);
}
OpaqueTokenAuthenticationConverter getAuthenticationConverter() {
if (this.authenticationConverter != null) {
return this.authenticationConverter;
}
if (this.context.getBeanNamesForType(OpaqueTokenAuthenticationConverter.class).length > 0) {
return this.context.getBean(OpaqueTokenAuthenticationConverter.class);
}
return null;
}
AuthenticationProvider getAuthenticationProvider() {
if (this.authenticationManager != null) {
return null;
}
OpaqueTokenIntrospector introspector = getIntrospector();
return new OpaqueTokenAuthenticationProvider(introspector);
OpaqueTokenAuthenticationProvider opaqueTokenAuthenticationProvider = new OpaqueTokenAuthenticationProvider(
introspector);
OpaqueTokenAuthenticationConverter authenticationConverter = getAuthenticationConverter();
if (authenticationConverter != null) {
opaqueTokenAuthenticationProvider.setAuthenticationConverter(authenticationConverter);
}
return opaqueTokenAuthenticationProvider;
}
AuthenticationManager getAuthenticationManager(H http) {
@@ -244,6 +244,10 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
static final String CLIENT_SECRET = "client-secret";
static final String AUTHENTICATION_CONVERTER_REF = "authentication-converter-ref";
static final String AUTHENTICATION_CONVERTER = "authenticationConverter";
OpaqueTokenBeanDefinitionParser() {
}
@@ -251,9 +255,13 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
public BeanDefinition parse(Element element, ParserContext pc) {
validateConfiguration(element, pc);
BeanMetadataElement introspector = getIntrospector(element);
String authenticationConverterRef = element.getAttribute(AUTHENTICATION_CONVERTER_REF);
BeanDefinitionBuilder opaqueTokenProviderBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OpaqueTokenAuthenticationProvider.class);
opaqueTokenProviderBuilder.addConstructorArgValue(introspector);
if (StringUtils.hasText(authenticationConverterRef)) {
opaqueTokenProviderBuilder.addPropertyReference(AUTHENTICATION_CONVERTER, authenticationConverterRef);
}
return opaqueTokenProviderBuilder.getBeanDefinition();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -95,6 +95,7 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtRea
import org.springframework.security.oauth2.server.resource.authentication.OpaqueTokenReactiveAuthenticationManager;
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.introspection.NimbusReactiveOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.access.server.BearerTokenServerAccessDeniedHandler;
import org.springframework.security.oauth2.server.resource.web.server.BearerTokenServerAuthenticationEntryPoint;
@@ -4285,6 +4286,8 @@ public class ServerHttpSecurity {
private Supplier<ReactiveOpaqueTokenIntrospector> introspector;
private ReactiveOpaqueTokenAuthenticationConverter authenticationConverter;
private OpaqueTokenSpec() {
}
@@ -4323,6 +4326,13 @@ public class ServerHttpSecurity {
return this;
}
public OpaqueTokenSpec authenticationConverter(
ReactiveOpaqueTokenAuthenticationConverter authenticationConverter) {
Assert.notNull(authenticationConverter, "authenticationConverter cannot be null");
this.authenticationConverter = authenticationConverter;
return this;
}
/**
* Allows method chaining to continue configuring the
* {@link ServerHttpSecurity}
@@ -4333,7 +4343,13 @@ public class ServerHttpSecurity {
}
protected ReactiveAuthenticationManager getAuthenticationManager() {
return new OpaqueTokenReactiveAuthenticationManager(getIntrospector());
OpaqueTokenReactiveAuthenticationManager authenticationManager = new OpaqueTokenReactiveAuthenticationManager(
getIntrospector());
ReactiveOpaqueTokenAuthenticationConverter authenticationConverter = getAuthenticationConverter();
if (authenticationConverter != null) {
authenticationManager.setAuthenticationConverter(authenticationConverter);
}
return authenticationManager;
}
protected ReactiveOpaqueTokenIntrospector getIntrospector() {
@@ -4343,6 +4359,13 @@ public class ServerHttpSecurity {
return getBean(ReactiveOpaqueTokenIntrospector.class);
}
protected ReactiveOpaqueTokenAuthenticationConverter getAuthenticationConverter() {
if (this.authenticationConverter != null) {
return this.authenticationConverter;
}
return getBeanOrNull(ReactiveOpaqueTokenAuthenticationConverter.class);
}
protected void configure(ServerHttpSecurity http) {
ReactiveAuthenticationManager authenticationManager = getAuthenticationManager();
AuthenticationWebFilter oauth2 = new AuthenticationWebFilter(authenticationManager);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -20,6 +20,7 @@ import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer
import org.springframework.security.core.Authentication
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenAuthenticationConverter
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector
/**
@@ -54,6 +55,7 @@ class OpaqueTokenDsl {
clientCredentials = null
}
var authenticationConverter: OpaqueTokenAuthenticationConverter? = null
/**
* Configures the credentials for Introspection endpoint.
@@ -70,6 +72,7 @@ class OpaqueTokenDsl {
return { opaqueToken ->
introspectionUri?.also { opaqueToken.introspectionUri(introspectionUri) }
introspector?.also { opaqueToken.introspector(introspector) }
authenticationConverter?.also { opaqueToken.authenticationConverter(authenticationConverter) }
clientCredentials?.also { opaqueToken.introspectionClientCredentials(clientCredentials!!.first, clientCredentials!!.second) }
authenticationManager?.also { opaqueToken.authenticationManager(authenticationManager) }
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -16,6 +16,7 @@
package org.springframework.security.config.web.server
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenAuthenticationConverter
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector
/**
@@ -45,6 +46,7 @@ class ServerOpaqueTokenDsl {
_introspectionUri = null
clientCredentials = null
}
var authenticationConverter: ReactiveOpaqueTokenAuthenticationConverter? = null
/**
* Configures the credentials for Introspection endpoint.
@@ -62,6 +64,7 @@ class ServerOpaqueTokenDsl {
introspectionUri?.also { opaqueToken.introspectionUri(introspectionUri) }
clientCredentials?.also { opaqueToken.introspectionClientCredentials(clientCredentials!!.first, clientCredentials!!.second) }
introspector?.also { opaqueToken.introspector(introspector) }
authenticationConverter?.also { opaqueToken.authenticationConverter(authenticationConverter) }
}
}
}
@@ -667,6 +667,9 @@ opaque-token.attlist &=
opaque-token.attlist &=
## Reference to an OpaqueTokenIntrospector
attribute introspector-ref {xsd:token}?
opaque-token.attlist &=
## Reference to an OpaqueTokenAuthenticationConverter responsible for converting successful introspection result into an Authentication.
attribute authentication-converter-ref {xsd:token}?
openid-login =
## Sets up form login for authentication with an Open ID identity. NOTE: The OpenID 1.0 and 2.0 protocols have been deprecated and users are <a href="https://openid.net/specs/openid-connect-migration-1_0.html">encouraged to migrate</a> to <a href="https://openid.net/connect/">OpenID Connect</a>, which is supported by <code>spring-security-oauth2</code>.
@@ -2060,6 +2060,13 @@
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="authentication-converter-ref" type="xs:token">
<xs:annotation>
<xs:documentation>Reference to an OpaqueTokenAuthenticationConverter responsible for converting successful
introspection result into an Authentication.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
<xs:element name="attribute-exchange">
@@ -80,6 +80,7 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationManagerResolver;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
@@ -98,6 +99,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
@@ -116,6 +118,7 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtIssuerAuthenticationManagerResolver;
import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter;
@@ -1353,6 +1356,22 @@ public class OAuth2ResourceServerConfigurerTests {
.isThrownBy(jwtConfigurer::getJwtAuthenticationConverter);
}
@Test
public void getWhenCustomAuthenticationConverterThenConverts() throws Exception {
this.spring.register(RestOperationsConfig.class, OpaqueTokenAuthenticationConverterConfig.class,
BasicController.class).autowire();
OpaqueTokenAuthenticationConverter authenticationConverter = this.spring.getContext()
.getBean(OpaqueTokenAuthenticationConverter.class);
given(authenticationConverter.convert(anyString(), any(OAuth2AuthenticatedPrincipal.class)))
.willReturn(new TestingAuthenticationToken("jdoe", null, Collections.emptyList()));
mockRestOperations(json("Active"));
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken("token")))
.andExpect(status().isOk())
.andExpect(content().string("jdoe"));
// @formatter:on
}
private static <T> void registerMockBean(GenericApplicationContext context, String name, Class<T> clazz) {
context.registerBean(name, clazz, () -> mock(clazz));
}
@@ -2444,6 +2463,30 @@ public class OAuth2ResourceServerConfigurerTests {
}
@EnableWebSecurity
static class OpaqueTokenAuthenticationConverterConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/requires-read-scope").hasAuthority("SCOPE_message:read")
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.opaqueToken()
.authenticationConverter(authenticationConverter());
// @formatter:on
}
@Bean
OpaqueTokenAuthenticationConverter authenticationConverter() {
return mock(OpaqueTokenAuthenticationConverter.class);
}
}
@Configuration
static class JwtDecoderConfig {
@@ -23,6 +23,7 @@ import java.security.interfaces.RSAPublicKey;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -66,12 +67,16 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManagerResolver;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.JwtBeanDefinitionParser;
import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.OpaqueTokenBeanDefinitionParser;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
@@ -84,6 +89,7 @@ import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.jwt.TestJwts;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
@@ -643,6 +649,20 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
// @formatter:on
}
@Test
public void configureWhenIntrospectingWithAuthenticationConverterThenUses() throws Exception {
this.spring.configLocations(xml("OpaqueTokenRestOperations"), xml("OpaqueTokenAndAuthenticationConverter"))
.autowire();
mockRestOperations(json("Active"));
// @formatter:off
this.mvc.perform(get("/authenticated").header("Authorization", "Bearer token"))
.andExpect(status().isNotFound());
this.mvc.perform(get("/authenticated").header("Authorization", "Bearer invalidToken"))
.andExpect(status().isUnauthorized());
// @formatter:on
}
@Test
public void getWhenIntrospectionFailsThenUnauthorized() throws Exception {
this.spring.configLocations(xml("OpaqueTokenRestOperations"), xml("OpaqueToken")).autowire();
@@ -1077,4 +1097,39 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
}
public static class TestAuthentication extends AbstractAuthenticationToken {
private final String introspectedToken;
public TestAuthentication(String introspectedToken, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.introspectedToken = introspectedToken;
}
@Override
public Object getCredentials() {
return this.introspectedToken;
}
@Override
public Object getPrincipal() {
return this.introspectedToken;
}
@Override
public boolean isAuthenticated() {
return "token".equals(this.introspectedToken);
}
}
public static class TestOpaqueTokenAuthenticationConverter implements OpaqueTokenAuthenticationConverter {
@Override
public Authentication convert(String introspectedToken, OAuth2AuthenticatedPrincipal authenticatedPrincipal) {
return new TestAuthentication(introspectedToken, Collections.emptyList());
}
}
}
@@ -24,6 +24,7 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;
import java.util.Collections;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -52,11 +53,13 @@ import org.springframework.http.MediaType;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.ReactiveAuthenticationManagerResolver;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.jwt.Jwt;
@@ -66,6 +69,7 @@ import org.springframework.security.oauth2.server.resource.BearerTokenAuthentica
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenAuthenticationConverter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
@@ -566,6 +570,25 @@ public class OAuth2ResourceServerSpecTests {
.withMessageContaining("authenticationManagerResolver");
}
@Test
public void getWhenCustomAuthenticationConverterThenConverts() {
this.spring.register(ReactiveOpaqueTokenAuthenticationConverterConfig.class, RootController.class).autowire();
this.spring.getContext().getBean(MockWebServer.class)
.setDispatcher(requiresAuth(this.clientId, this.clientSecret, this.active));
ReactiveOpaqueTokenAuthenticationConverter authenticationConverter = this.spring.getContext()
.getBean(ReactiveOpaqueTokenAuthenticationConverter.class);
given(authenticationConverter.convert(anyString(), any(OAuth2AuthenticatedPrincipal.class)))
.willReturn(Mono.just(new TestingAuthenticationToken("jdoe", null, Collections.emptyList())));
// @formatter:off
this.client.get()
.headers((headers) -> headers
.setBearerAuth(this.messageReadToken)
)
.exchange()
.expectStatus().isOk();
// @formatter:on
}
private static Dispatcher requiresAuth(String username, String password, String response) {
return new Dispatcher() {
@Override
@@ -1052,6 +1075,43 @@ public class OAuth2ResourceServerSpecTests {
}
@EnableWebFlux
@EnableWebFluxSecurity
static class ReactiveOpaqueTokenAuthenticationConverterConfig {
private MockWebServer mockWebServer = new MockWebServer();
@Bean
SecurityWebFilterChain springSecurity(ServerHttpSecurity http) {
String introspectionUri = mockWebServer().url("/introspect").toString();
// @formatter:off
http
.oauth2ResourceServer()
.opaqueToken()
.introspectionUri(introspectionUri)
.introspectionClientCredentials("client", "secret")
.authenticationConverter(authenticationConverter());
// @formatter:on
return http.build();
}
@Bean
ReactiveOpaqueTokenAuthenticationConverter authenticationConverter() {
return mock(ReactiveOpaqueTokenAuthenticationConverter.class);
}
@Bean
MockWebServer mockWebServer() {
return this.mockWebServer;
}
@PreDestroy
void shutdown() throws IOException {
this.mockWebServer.shutdown();
}
}
@RestController
static class RootController {
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2002-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.
-->
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<b:bean name="authentication-converter"
class="org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParserTests$TestOpaqueTokenAuthenticationConverter">
</b:bean>
<http>
<intercept-url pattern="/requires-read-scope" access="hasAuthority('SCOPE_message:read')"/>
<intercept-url pattern="/**" access="authenticated"/>
<oauth2-resource-server>
<opaque-token introspector-ref="introspector" authentication-converter-ref="authentication-converter"/>
</oauth2-resource-server>
</http>
<b:import resource="userservice.xml"/>
</b:beans>