mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-04 17:52:15 +00:00
Load ReactiveJwtAuthenticationConverter bean in OAuth2 Resource Server config
When a bean of type ReactiveJwtAuthenticationConverter is defined, the OAuth2 Resource Server configuration will use it automatically when no other converter is defined through the DSL. Closes gh-9698
This commit is contained in:
parent
98326dfae4
commit
b44d0fb319
@ -91,10 +91,9 @@ import org.springframework.security.oauth2.jwt.Jwt;
|
|||||||
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
||||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoderFactory;
|
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoderFactory;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager;
|
import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.OpaqueTokenReactiveAuthenticationManager;
|
import org.springframework.security.oauth2.server.resource.authentication.OpaqueTokenReactiveAuthenticationManager;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
|
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.NimbusReactiveOpaqueTokenIntrospector;
|
||||||
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
|
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.access.server.BearerTokenServerAccessDeniedHandler;
|
||||||
@ -1497,6 +1496,13 @@ public class ServerHttpSecurity {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> String[] getBeanNamesForTypeOrEmpty(Class<T> beanClass) {
|
||||||
|
if (this.context == null) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
return this.context.getBeanNamesForType(beanClass);
|
||||||
|
}
|
||||||
|
|
||||||
protected void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
protected void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
this.context = applicationContext;
|
this.context = applicationContext;
|
||||||
}
|
}
|
||||||
@ -3813,8 +3819,7 @@ public class ServerHttpSecurity {
|
|||||||
|
|
||||||
private ReactiveJwtDecoder jwtDecoder;
|
private ReactiveJwtDecoder jwtDecoder;
|
||||||
|
|
||||||
private Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> jwtAuthenticationConverter = new ReactiveJwtAuthenticationConverterAdapter(
|
private Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> jwtAuthenticationConverter;
|
||||||
new JwtAuthenticationConverter());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the {@link ReactiveAuthenticationManager} to use
|
* Configures the {@link ReactiveAuthenticationManager} to use
|
||||||
@ -3892,9 +3897,18 @@ public class ServerHttpSecurity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> getJwtAuthenticationConverter() {
|
protected Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> getJwtAuthenticationConverter() {
|
||||||
|
if (this.jwtAuthenticationConverter != null) {
|
||||||
return this.jwtAuthenticationConverter;
|
return this.jwtAuthenticationConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getBeanNamesForTypeOrEmpty(ReactiveJwtAuthenticationConverter.class).length > 0) {
|
||||||
|
return getBean(ReactiveJwtAuthenticationConverter.class);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new ReactiveJwtAuthenticationConverter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ReactiveAuthenticationManager getAuthenticationManager() {
|
private ReactiveAuthenticationManager getAuthenticationManager() {
|
||||||
if (this.authenticationManager != null) {
|
if (this.authenticationManager != null) {
|
||||||
return this.authenticationManager;
|
return this.authenticationManager;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2021 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.
|
||||||
@ -64,6 +64,7 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
|||||||
import org.springframework.security.oauth2.jwt.TestJwts;
|
import org.springframework.security.oauth2.jwt.TestJwts;
|
||||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
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.authentication.ReactiveJwtAuthenticationConverterAdapter;
|
||||||
import org.springframework.security.web.server.SecurityWebFilterChain;
|
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||||
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
|
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
|
||||||
@ -478,6 +479,58 @@ public class OAuth2ResourceServerSpecTests {
|
|||||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() -> jwt.getJwtDecoder());
|
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() -> jwt.getJwtDecoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getJwtAuthenticationConverterWhenBeanWiredAndDslWiredThenDslTakesPrecedence() {
|
||||||
|
GenericWebApplicationContext context = autowireWebServerGenericWebApplicationContext();
|
||||||
|
ServerHttpSecurity http = new ServerHttpSecurity();
|
||||||
|
http.setApplicationContext(context);
|
||||||
|
ReactiveJwtAuthenticationConverter beanWiredJwtAuthenticationConverter = new ReactiveJwtAuthenticationConverter();
|
||||||
|
ReactiveJwtAuthenticationConverter dslWiredJwtAuthenticationConverter = new ReactiveJwtAuthenticationConverter();
|
||||||
|
context.registerBean(ReactiveJwtAuthenticationConverter.class, () -> beanWiredJwtAuthenticationConverter);
|
||||||
|
ServerHttpSecurity.OAuth2ResourceServerSpec.JwtSpec jwt = http.oauth2ResourceServer().jwt();
|
||||||
|
jwt.jwtAuthenticationConverter(dslWiredJwtAuthenticationConverter);
|
||||||
|
assertThat(jwt.getJwtAuthenticationConverter()).isEqualTo(dslWiredJwtAuthenticationConverter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getJwtAuthenticationConverterWhenTwoBeansWiredAndDslWiredThenDslTakesPrecedence() {
|
||||||
|
GenericWebApplicationContext context = autowireWebServerGenericWebApplicationContext();
|
||||||
|
ServerHttpSecurity http = new ServerHttpSecurity();
|
||||||
|
http.setApplicationContext(context);
|
||||||
|
ReactiveJwtAuthenticationConverter beanWiredJwtAuthenticationConverter = new ReactiveJwtAuthenticationConverter();
|
||||||
|
ReactiveJwtAuthenticationConverter dslWiredJwtAuthenticationConverter = new ReactiveJwtAuthenticationConverter();
|
||||||
|
context.registerBean("firstJwtAuthenticationConverter", ReactiveJwtAuthenticationConverter.class,
|
||||||
|
() -> beanWiredJwtAuthenticationConverter);
|
||||||
|
context.registerBean("secondJwtAuthenticationConverter", ReactiveJwtAuthenticationConverter.class,
|
||||||
|
() -> beanWiredJwtAuthenticationConverter);
|
||||||
|
ServerHttpSecurity.OAuth2ResourceServerSpec.JwtSpec jwt = http.oauth2ResourceServer().jwt();
|
||||||
|
jwt.jwtAuthenticationConverter(dslWiredJwtAuthenticationConverter);
|
||||||
|
assertThat(jwt.getJwtAuthenticationConverter()).isEqualTo(dslWiredJwtAuthenticationConverter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getJwtAuthenticationConverterWhenTwoBeansWiredThenThrowsWiringException() {
|
||||||
|
GenericWebApplicationContext context = autowireWebServerGenericWebApplicationContext();
|
||||||
|
ServerHttpSecurity http = new ServerHttpSecurity();
|
||||||
|
http.setApplicationContext(context);
|
||||||
|
ReactiveJwtAuthenticationConverter beanWiredJwtAuthenticationConverter = new ReactiveJwtAuthenticationConverter();
|
||||||
|
context.registerBean("firstJwtAuthenticationConverter", ReactiveJwtAuthenticationConverter.class,
|
||||||
|
() -> beanWiredJwtAuthenticationConverter);
|
||||||
|
context.registerBean("secondJwtAuthenticationConverter", ReactiveJwtAuthenticationConverter.class,
|
||||||
|
() -> beanWiredJwtAuthenticationConverter);
|
||||||
|
ServerHttpSecurity.OAuth2ResourceServerSpec.JwtSpec jwt = http.oauth2ResourceServer().jwt();
|
||||||
|
assertThatExceptionOfType(NoUniqueBeanDefinitionException.class).isThrownBy(jwt::getJwtAuthenticationConverter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getJwtAuthenticationConverterWhenNoBeansAndNoDslWiredThenDefaultConverter() {
|
||||||
|
GenericWebApplicationContext context = autowireWebServerGenericWebApplicationContext();
|
||||||
|
ServerHttpSecurity http = new ServerHttpSecurity();
|
||||||
|
http.setApplicationContext(context);
|
||||||
|
ServerHttpSecurity.OAuth2ResourceServerSpec.JwtSpec jwt = http.oauth2ResourceServer().jwt();
|
||||||
|
assertThat(jwt.getJwtAuthenticationConverter()).isInstanceOf(ReactiveJwtAuthenticationConverter.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void introspectWhenValidThenReturnsOk() {
|
public void introspectWhenValidThenReturnsOk() {
|
||||||
this.spring.register(IntrospectionConfig.class, RootController.class).autowire();
|
this.spring.register(IntrospectionConfig.class, RootController.class).autowire();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user