@ -127,6 +127,7 @@ import static org.mockito.Mockito.mock;
@@ -127,6 +127,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never ;
import static org.mockito.Mockito.verify ;
import static org.mockito.Mockito.when ;
import static org.springframework.security.config.Customizer.withDefaults ;
import static org.springframework.security.oauth2.core.TestOAuth2AccessTokens.noScopes ;
import static org.springframework.security.oauth2.jwt.NimbusJwtDecoder.withJwkSetUri ;
import static org.springframework.security.oauth2.jwt.NimbusJwtDecoder.withPublicKey ;
@ -184,6 +185,19 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -184,6 +185,19 @@ public class OAuth2ResourceServerConfigurerTests {
. andExpect ( content ( ) . string ( "ok" ) ) ;
}
@Test
public void getWhenUsingDefaultsInLambdaWithValidBearerTokenThenAcceptsRequest ( )
throws Exception {
this . spring . register ( RestOperationsConfig . class , DefaultInLambdaConfig . class , BasicController . class ) . autowire ( ) ;
mockRestOperations ( jwks ( "Default" ) ) ;
String token = this . token ( "ValidNoScopes" ) ;
this . mvc . perform ( get ( "/" ) . with ( bearerToken ( token ) ) )
. andExpect ( status ( ) . isOk ( ) )
. andExpect ( content ( ) . string ( "ok" ) ) ;
}
@Test
public void getWhenUsingJwkSetUriThenAcceptsRequest ( ) throws Exception {
this . spring . register ( WebServerConfig . class , JwkSetUriConfig . class , BasicController . class ) . autowire ( ) ;
@ -195,6 +209,16 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -195,6 +209,16 @@ public class OAuth2ResourceServerConfigurerTests {
. andExpect ( content ( ) . string ( "ok" ) ) ;
}
@Test
public void getWhenUsingJwkSetUriInLambdaThenAcceptsRequest ( ) throws Exception {
this . spring . register ( WebServerConfig . class , JwkSetUriInLambdaConfig . class , BasicController . class ) . autowire ( ) ;
mockWebServer ( jwks ( "Default" ) ) ;
String token = this . token ( "ValidNoScopes" ) ;
this . mvc . perform ( get ( "/" ) . with ( bearerToken ( token ) ) )
. andExpect ( status ( ) . isOk ( ) )
. andExpect ( content ( ) . string ( "ok" ) ) ;
}
@Test
public void getWhenUsingDefaultsWithExpiredBearerTokenThenInvalidToken ( )
@ -756,6 +780,23 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -756,6 +780,23 @@ public class OAuth2ResourceServerConfigurerTests {
. andExpect ( content ( ) . string ( JWT_SUBJECT ) ) ;
}
@Test
public void requestWhenCustomJwtDecoderInLambdaOnDslThenUsed ( )
throws Exception {
this . spring . register ( CustomJwtDecoderInLambdaOnDsl . class , BasicController . class ) . autowire ( ) ;
CustomJwtDecoderInLambdaOnDsl config = this . spring . getContext ( ) . getBean ( CustomJwtDecoderInLambdaOnDsl . class ) ;
JwtDecoder decoder = config . decoder ( ) ;
when ( decoder . decode ( anyString ( ) ) ) . thenReturn ( JWT ) ;
this . mvc . perform ( get ( "/authenticated" )
. with ( bearerToken ( JWT_TOKEN ) ) )
. andExpect ( status ( ) . isOk ( ) )
. andExpect ( content ( ) . string ( JWT_SUBJECT ) ) ;
}
@Test
public void requestWhenCustomJwtDecoderExposedAsBeanThenUsed ( )
throws Exception {
@ -1067,6 +1108,17 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -1067,6 +1108,17 @@ public class OAuth2ResourceServerConfigurerTests {
. andExpect ( content ( ) . string ( "test-subject" ) ) ;
}
@Test
public void getWhenOpaqueTokenInLambdaAndIntrospectingThenOk ( ) throws Exception {
this . spring . register ( RestOperationsConfig . class , OpaqueTokenInLambdaConfig . class , BasicController . class ) . autowire ( ) ;
mockRestOperations ( json ( "Active" ) ) ;
this . mvc . perform ( get ( "/authenticated" )
. with ( bearerToken ( "token" ) ) )
. andExpect ( status ( ) . isOk ( ) )
. andExpect ( content ( ) . string ( "test-subject" ) ) ;
}
@Test
public void getWhenIntrospectionFailsThenUnauthorized ( ) throws Exception {
this . spring . register ( RestOperationsConfig . class , OpaqueTokenConfig . class ) . autowire ( ) ;
@ -1104,6 +1156,20 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -1104,6 +1156,20 @@ public class OAuth2ResourceServerConfigurerTests {
verifyBean ( AuthenticationProvider . class ) . authenticate ( any ( Authentication . class ) ) ;
}
@Test
public void getWhenCustomIntrospectionAuthenticationManagerInLambdaThenUsed ( ) throws Exception {
this . spring . register ( OpaqueTokenAuthenticationManagerInLambdaConfig . class , BasicController . class ) . autowire ( ) ;
when ( bean ( AuthenticationProvider . class ) . authenticate ( any ( Authentication . class ) ) )
. thenReturn ( INTROSPECTION_AUTHENTICATION_TOKEN ) ;
this . mvc . perform ( get ( "/authenticated" )
. with ( bearerToken ( "token" ) ) )
. andExpect ( status ( ) . isOk ( ) )
. andExpect ( content ( ) . string ( "mock-test-subject" ) ) ;
verifyBean ( AuthenticationProvider . class ) . authenticate ( any ( Authentication . class ) ) ;
}
@Test
public void configureWhenOnlyIntrospectionUrlThenException ( ) throws Exception {
assertThatCode ( ( ) - > this . spring . register ( OpaqueTokenHalfConfiguredConfig . class ) . autowire ( ) )
@ -1311,6 +1377,26 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -1311,6 +1377,26 @@ public class OAuth2ResourceServerConfigurerTests {
}
}
@EnableWebSecurity
static class DefaultInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure ( HttpSecurity http ) throws Exception {
// @formatter:off
http
. authorizeRequests ( authorizeRequests - >
authorizeRequests
. antMatchers ( "/requires-read-scope" ) . access ( "hasAuthority('SCOPE_message:read')" )
. anyRequest ( ) . authenticated ( )
)
. oauth2ResourceServer ( oauth2ResourceServer - >
oauth2ResourceServer
. jwt ( withDefaults ( ) )
) ;
// @formatter:on
}
}
@EnableWebSecurity
static class JwkSetUriConfig extends WebSecurityConfigurerAdapter {
@Value ( "${mockwebserver.url:https://example.org}" )
@ -1331,6 +1417,31 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -1331,6 +1417,31 @@ public class OAuth2ResourceServerConfigurerTests {
}
}
@EnableWebSecurity
static class JwkSetUriInLambdaConfig extends WebSecurityConfigurerAdapter {
@Value ( "${mockwebserver.url:https://example.org}" )
String jwkSetUri ;
@Override
protected void configure ( HttpSecurity http ) throws Exception {
// @formatter:off
http
. authorizeRequests ( authorizeRequests - >
authorizeRequests
. antMatchers ( "/requires-read-scope" ) . access ( "hasAuthority('SCOPE_message:read')" )
. anyRequest ( ) . authenticated ( )
)
. oauth2ResourceServer ( oauth2ResourceServer - >
oauth2ResourceServer
. jwt ( jwt - >
jwt
. jwkSetUri ( this . jwkSetUri )
)
) ;
// @formatter:on
}
}
@EnableWebSecurity
static class CsrfDisabledConfig extends WebSecurityConfigurerAdapter {
@Value ( "${mockwebserver.url:https://example.org}" )
@ -1677,6 +1788,33 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -1677,6 +1788,33 @@ public class OAuth2ResourceServerConfigurerTests {
}
}
@EnableWebSecurity
static class CustomJwtDecoderInLambdaOnDsl extends WebSecurityConfigurerAdapter {
JwtDecoder decoder = mock ( JwtDecoder . class ) ;
@Override
protected void configure ( HttpSecurity http ) throws Exception {
// @formatter:off
http
. authorizeRequests ( authorizeRequests - >
authorizeRequests
. anyRequest ( ) . authenticated ( )
)
. oauth2ResourceServer ( oauth2ResourceServer - >
oauth2ResourceServer
. jwt ( jwt - >
jwt
. decoder ( decoder ( ) )
)
) ;
// @formatter:on
}
JwtDecoder decoder ( ) {
return this . decoder ;
}
}
@EnableWebSecurity
static class CustomJwtDecoderAsBean extends WebSecurityConfigurerAdapter {
@Override
@ -1831,6 +1969,25 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -1831,6 +1969,25 @@ public class OAuth2ResourceServerConfigurerTests {
}
}
@EnableWebSecurity
static class OpaqueTokenInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure ( HttpSecurity http ) throws Exception {
// @formatter:off
http
. authorizeRequests ( authorizeRequests - >
authorizeRequests
. antMatchers ( "/requires-read-scope" ) . hasAuthority ( "SCOPE_message:read" )
. anyRequest ( ) . authenticated ( )
)
. oauth2ResourceServer ( oauth2ResourceServer - >
oauth2ResourceServer
. opaqueToken ( withDefaults ( ) )
) ;
// @formatter:on
}
}
@EnableWebSecurity
static class OpaqueTokenAuthenticationManagerConfig extends WebSecurityConfigurerAdapter {
@Override
@ -1852,6 +2009,32 @@ public class OAuth2ResourceServerConfigurerTests {
@@ -1852,6 +2009,32 @@ public class OAuth2ResourceServerConfigurerTests {
}
}
@EnableWebSecurity
static class OpaqueTokenAuthenticationManagerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure ( HttpSecurity http ) throws Exception {
// @formatter:off
http
. authorizeRequests ( authorizeRequests - >
authorizeRequests
. anyRequest ( ) . authenticated ( )
)
. oauth2ResourceServer ( oauth2ResourceServer - >
oauth2ResourceServer
. opaqueToken ( opaqueToken - >
opaqueToken
. authenticationManager ( authenticationProvider ( ) : : authenticate )
)
) ;
// @formatter:on
}
@Bean
public AuthenticationProvider authenticationProvider ( ) {
return mock ( AuthenticationProvider . class ) ;
}
}
@EnableWebSecurity
static class OpaqueAndJwtConfig extends WebSecurityConfigurerAdapter {
@Override