Add SecurityAssertions
This commit introduces a simple, internal test API for verifying aspects of an Authentication, like its name and authorities. Closes gh-17844
This commit is contained in:
+1
-1
@@ -165,7 +165,7 @@ public class OAuth2LoginAuthenticationProviderTests {
|
||||
assertThat(authentication.isAuthenticated()).isTrue();
|
||||
assertThat(authentication.getPrincipal()).isEqualTo(principal);
|
||||
assertThat(authentication.getCredentials()).isEqualTo("");
|
||||
assertThat(authentication.getAuthorities()).isEqualTo(authorities);
|
||||
assertThat(authentication.getAuthorities()).containsAll(authorities);
|
||||
assertThat(authentication.getClientRegistration()).isEqualTo(this.clientRegistration);
|
||||
assertThat(authentication.getAuthorizationExchange()).isEqualTo(this.authorizationExchange);
|
||||
assertThat(authentication.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken());
|
||||
|
||||
@@ -14,6 +14,7 @@ dependencies {
|
||||
|
||||
provided 'jakarta.servlet:jakarta.servlet-api'
|
||||
|
||||
testImplementation project(path : ':spring-security-core', configuration : 'tests')
|
||||
testImplementation project(path: ':spring-security-oauth2-jose', configuration: 'tests')
|
||||
testImplementation 'com.squareup.okhttp3:mockwebserver'
|
||||
testImplementation 'com.fasterxml.jackson.core:jackson-databind'
|
||||
@@ -27,5 +28,6 @@ dependencies {
|
||||
testImplementation "org.mockito:mockito-junit-jupiter"
|
||||
testImplementation "org.springframework:spring-test"
|
||||
|
||||
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
}
|
||||
|
||||
+3
-5
@@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
@@ -46,9 +47,7 @@ public class JwtAuthenticationConverterTests {
|
||||
public void convertWhenDefaultGrantedAuthoritiesConverterSet() {
|
||||
Jwt jwt = TestJwts.jwt().claim("scope", "message:read message:write").build();
|
||||
AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt);
|
||||
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
assertThat(authorities).containsExactly(new SimpleGrantedAuthority("SCOPE_message:read"),
|
||||
new SimpleGrantedAuthority("SCOPE_message:write"));
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("SCOPE_message:read", "SCOPE_message:write");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -65,8 +64,7 @@ public class JwtAuthenticationConverterTests {
|
||||
.asList(new SimpleGrantedAuthority("blah"));
|
||||
this.jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
|
||||
AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt);
|
||||
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
assertThat(authorities).containsExactly(new SimpleGrantedAuthority("blah"));
|
||||
SecurityAssertions.assertThat(authentication).hasAuthority("blah");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+10
-6
@@ -17,11 +17,13 @@
|
||||
package org.springframework.security.oauth2.server.resource.authentication;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -48,7 +50,7 @@ public class JwtBearerTokenAuthenticationConverterTests {
|
||||
BearerTokenAuthentication bearerToken = (BearerTokenAuthentication) token;
|
||||
assertThat(bearerToken.getToken().getTokenValue()).isEqualTo("token-value");
|
||||
assertThat(bearerToken.getTokenAttributes()).containsOnlyKeys("claim");
|
||||
assertThat(bearerToken.getAuthorities()).isEmpty();
|
||||
assertThat(bearerToken.getAuthorities()).noneMatch(isScope());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -62,8 +64,7 @@ public class JwtBearerTokenAuthenticationConverterTests {
|
||||
AbstractAuthenticationToken token = this.converter.convert(jwt);
|
||||
assertThat(token).isInstanceOf(BearerTokenAuthentication.class);
|
||||
BearerTokenAuthentication bearerToken = (BearerTokenAuthentication) token;
|
||||
assertThat(bearerToken.getAuthorities()).containsExactly(new SimpleGrantedAuthority("SCOPE_message:read"),
|
||||
new SimpleGrantedAuthority("SCOPE_message:write"));
|
||||
SecurityAssertions.assertThat(bearerToken).hasAuthorities("SCOPE_message:read", "SCOPE_message:write");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,8 +78,11 @@ public class JwtBearerTokenAuthenticationConverterTests {
|
||||
AbstractAuthenticationToken token = this.converter.convert(jwt);
|
||||
assertThat(token).isInstanceOf(BearerTokenAuthentication.class);
|
||||
BearerTokenAuthentication bearerToken = (BearerTokenAuthentication) token;
|
||||
assertThat(bearerToken.getAuthorities()).containsExactly(new SimpleGrantedAuthority("SCOPE_message:read"),
|
||||
new SimpleGrantedAuthority("SCOPE_message:write"));
|
||||
SecurityAssertions.assertThat(bearerToken).hasAuthorities("SCOPE_message:read", "SCOPE_message:write");
|
||||
}
|
||||
|
||||
static Predicate<GrantedAuthority> isScope() {
|
||||
return (a) -> a.getAuthority().startsWith("SCOPE_");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-6
@@ -23,10 +23,10 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.jwt.BadJwtException;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
@@ -137,11 +137,7 @@ public class JwtReactiveAuthenticationManagerTests {
|
||||
Authentication authentication = this.manager.authenticate(token).block();
|
||||
assertThat(authentication).isNotNull();
|
||||
assertThat(authentication.isAuthenticated()).isTrue();
|
||||
// @formatter:off
|
||||
assertThat(authentication.getAuthorities())
|
||||
.extracting(GrantedAuthority::getAuthority)
|
||||
.containsOnly("SCOPE_message:read", "SCOPE_message:write");
|
||||
// @formatter:on
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("SCOPE_message:read", "SCOPE_message:write");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-5
@@ -21,12 +21,15 @@ import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
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.OAuth2TokenIntrospectionClaimNames;
|
||||
import org.springframework.security.oauth2.core.TestOAuth2AuthenticatedPrincipals;
|
||||
@@ -75,10 +78,7 @@ public class OpaqueTokenAuthenticationProviderTests {
|
||||
.containsEntry(OAuth2TokenIntrospectionClaimNames.SUB, "Z5O3upPC88QrAjx00dis")
|
||||
.containsEntry(OAuth2TokenIntrospectionClaimNames.USERNAME, "jdoe")
|
||||
.containsEntry("extension_field", "twenty-seven");
|
||||
assertThat(result.getAuthorities())
|
||||
.extracting("authority")
|
||||
.containsExactly("SCOPE_read", "SCOPE_write",
|
||||
"SCOPE_dolphin");
|
||||
SecurityAssertions.assertThat(result).hasAuthorities("SCOPE_read", "SCOPE_write", "SCOPE_dolphin");
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class OpaqueTokenAuthenticationProviderTests {
|
||||
.isNotNull()
|
||||
.doesNotContainKey(OAuth2TokenIntrospectionClaimNames.SCOPE);
|
||||
// @formatter:on
|
||||
assertThat(result.getAuthorities()).isEmpty();
|
||||
SecurityAssertions.assertThat(result).authorities().noneMatch(isScope());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,4 +146,8 @@ public class OpaqueTokenAuthenticationProviderTests {
|
||||
verifyNoMoreInteractions(introspector, authenticationConverter);
|
||||
}
|
||||
|
||||
static Predicate<GrantedAuthority> isScope() {
|
||||
return (a) -> a.getAuthority().startsWith("SCOPE_");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-5
@@ -21,13 +21,16 @@ import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
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.OAuth2TokenIntrospectionClaimNames;
|
||||
import org.springframework.security.oauth2.core.TestOAuth2AuthenticatedPrincipals;
|
||||
@@ -76,10 +79,7 @@ public class OpaqueTokenReactiveAuthenticationManagerTests {
|
||||
.containsEntry(OAuth2TokenIntrospectionClaimNames.SUB, "Z5O3upPC88QrAjx00dis")
|
||||
.containsEntry(OAuth2TokenIntrospectionClaimNames.USERNAME, "jdoe")
|
||||
.containsEntry("extension_field", "twenty-seven");
|
||||
assertThat(result.getAuthorities())
|
||||
.extracting("authority")
|
||||
.containsExactly("SCOPE_read", "SCOPE_write",
|
||||
"SCOPE_dolphin");
|
||||
SecurityAssertions.assertThat(result).hasAuthorities("SCOPE_read", "SCOPE_write", "SCOPE_dolphin");
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public class OpaqueTokenReactiveAuthenticationManagerTests {
|
||||
assertThat(result.getPrincipal()).isInstanceOf(OAuth2IntrospectionAuthenticatedPrincipal.class);
|
||||
Map<String, Object> attributes = ((OAuth2AuthenticatedPrincipal) result.getPrincipal()).getAttributes();
|
||||
assertThat(attributes).isNotNull().doesNotContainKey(OAuth2TokenIntrospectionClaimNames.SCOPE);
|
||||
assertThat(result.getAuthorities()).isEmpty();
|
||||
SecurityAssertions.assertThat(result).authorities().noneMatch(isScope());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -145,4 +145,8 @@ public class OpaqueTokenReactiveAuthenticationManagerTests {
|
||||
verifyNoMoreInteractions(introspector, authenticationConverter);
|
||||
}
|
||||
|
||||
static Predicate<GrantedAuthority> isScope() {
|
||||
return (a) -> a.getAuthority().startsWith("SCOPE_");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-28
@@ -17,19 +17,17 @@
|
||||
package org.springframework.security.oauth2.server.resource.authentication;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.TestJwts;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReactiveJwtAuthenticationConverterAdapter}
|
||||
*
|
||||
@@ -46,40 +44,28 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
|
||||
public void convertWhenTokenHasScopeAttributeThenTranslatedToAuthorities() {
|
||||
Jwt jwt = TestJwts.jwt().claim("scope", "message:read message:write").build();
|
||||
AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
|
||||
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
// @formatter:off
|
||||
assertThat(authorities)
|
||||
.containsExactly(new SimpleGrantedAuthority("SCOPE_message:read"),
|
||||
new SimpleGrantedAuthority("SCOPE_message:write"));
|
||||
// @formatter:on
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("SCOPE_message:read", "SCOPE_message:write");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertWhenTokenHasEmptyScopeAttributeThenTranslatedToNoAuthorities() {
|
||||
Jwt jwt = TestJwts.jwt().claim("scope", "").build();
|
||||
AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
|
||||
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
assertThat(authorities).containsExactly();
|
||||
SecurityAssertions.assertThat(authentication).authorities().noneMatch(isScope());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertWhenTokenHasScpAttributeThenTranslatedToAuthorities() {
|
||||
Jwt jwt = TestJwts.jwt().claim("scp", Arrays.asList("message:read", "message:write")).build();
|
||||
AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
|
||||
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
// @formatter:off
|
||||
assertThat(authorities)
|
||||
.containsExactly(new SimpleGrantedAuthority("SCOPE_message:read"),
|
||||
new SimpleGrantedAuthority("SCOPE_message:write"));
|
||||
// @formatter:on
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("SCOPE_message:read", "SCOPE_message:write");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertWhenTokenHasEmptyScpAttributeThenTranslatedToNoAuthorities() {
|
||||
Jwt jwt = TestJwts.jwt().claim("scp", Arrays.asList()).build();
|
||||
AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
|
||||
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
assertThat(authorities).containsExactly();
|
||||
SecurityAssertions.assertThat(authentication).authorities().noneMatch(isScope());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -89,12 +75,7 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
|
||||
.claim("scope", "missive:read missive:write")
|
||||
.build();
|
||||
AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
|
||||
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
// @formatter:off
|
||||
assertThat(authorities)
|
||||
.containsExactly(new SimpleGrantedAuthority("SCOPE_missive:read"),
|
||||
new SimpleGrantedAuthority("SCOPE_missive:write"));
|
||||
// @formatter:on
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("SCOPE_missive:read", "SCOPE_missive:write");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,8 +87,11 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
|
||||
.build();
|
||||
// @formatter:on
|
||||
AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
|
||||
Collection<GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
assertThat(authorities).containsExactly();
|
||||
SecurityAssertions.assertThat(authentication).authorities().noneMatch(isScope());
|
||||
}
|
||||
|
||||
static Predicate<GrantedAuthority> isScope() {
|
||||
return (a) -> a.getAuthority().startsWith("SCOPE_");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user