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:
parent
de10e08348
commit
c64b086878
|
@ -32,6 +32,7 @@ import org.springframework.security.authentication.AuthenticationEventPublisher;
|
|||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.ProviderManager;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.ObjectPostProcessor;
|
||||
|
@ -44,7 +45,6 @@ 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.AuthenticationException;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.PasswordEncodedUser;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
|
||||
|
@ -107,8 +107,7 @@ public class AuthenticationManagerBuilderTests {
|
|||
.getAuthenticationManager();
|
||||
Authentication auth = manager
|
||||
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("user", "password"));
|
||||
assertThat(auth.getName()).isEqualTo("user");
|
||||
assertThat(auth.getAuthorities()).extracting(GrantedAuthority::getAuthority).containsOnly("ROLE_USER");
|
||||
SecurityAssertions.assertThat(auth).name("user").hasAuthority("ROLE_USER");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -119,8 +118,7 @@ public class AuthenticationManagerBuilderTests {
|
|||
.getAuthenticationManager();
|
||||
Authentication auth = manager
|
||||
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("user", "password"));
|
||||
assertThat(auth.getName()).isEqualTo("user");
|
||||
assertThat(auth.getAuthorities()).extracting(GrantedAuthority::getAuthority).containsOnly("ROLE_USER");
|
||||
SecurityAssertions.assertThat(auth).name("user").hasAuthority("ROLE_USER");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.springframework.mock.web.MockFilterChain;
|
|||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.ObjectPostProcessor;
|
||||
|
@ -217,10 +218,9 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(1);
|
||||
assertThat(authentication.getAuthorities()).first()
|
||||
.isInstanceOf(OAuth2UserAuthority.class)
|
||||
.hasToString("OAUTH2_USER");
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.hasAuthority("OAUTH2_USER")
|
||||
.isInstanceOf(OAuth2UserAuthority.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -234,10 +234,9 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(1);
|
||||
assertThat(authentication.getAuthorities()).first()
|
||||
.isInstanceOf(OAuth2UserAuthority.class)
|
||||
.hasToString("OAUTH2_USER");
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.hasAuthority("OAUTH2_USER")
|
||||
.isInstanceOf(OAuth2UserAuthority.class);
|
||||
SecurityContextHolderStrategy strategy = this.context.getBean(SecurityContextHolderStrategy.class);
|
||||
verify(strategy, atLeastOnce()).getDeferredContext();
|
||||
SecurityContextChangedListener listener = this.context.getBean(SecurityContextChangedListener.class);
|
||||
|
@ -255,10 +254,9 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(1);
|
||||
assertThat(authentication.getAuthorities()).first()
|
||||
.isInstanceOf(OAuth2UserAuthority.class)
|
||||
.hasToString("OAUTH2_USER");
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.hasAuthority("OAUTH2_USER")
|
||||
.isInstanceOf(OAuth2UserAuthority.class);
|
||||
}
|
||||
|
||||
// gh-6009
|
||||
|
@ -296,9 +294,7 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(2);
|
||||
assertThat(authentication.getAuthorities()).first().hasToString("OAUTH2_USER");
|
||||
assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OAUTH2_USER");
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("OAUTH2_USER", "ROLE_OAUTH2_USER");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -317,9 +313,7 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(2);
|
||||
assertThat(authentication.getAuthorities()).first().hasToString("OAUTH2_USER");
|
||||
assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OAUTH2_USER");
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("OAUTH2_USER", "ROLE_OAUTH2_USER");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -338,9 +332,7 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(2);
|
||||
assertThat(authentication.getAuthorities()).first().hasToString("OAUTH2_USER");
|
||||
assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OAUTH2_USER");
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("OAUTH2_USER", "ROLE_OAUTH2_USER");
|
||||
}
|
||||
|
||||
// gh-5488
|
||||
|
@ -361,10 +353,9 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(1);
|
||||
assertThat(authentication.getAuthorities()).first()
|
||||
.isInstanceOf(OAuth2UserAuthority.class)
|
||||
.hasToString("OAUTH2_USER");
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.hasAuthority("OAUTH2_USER")
|
||||
.isInstanceOf(OAuth2UserAuthority.class);
|
||||
}
|
||||
|
||||
// gh-5521
|
||||
|
@ -570,10 +561,7 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(1);
|
||||
assertThat(authentication.getAuthorities()).first()
|
||||
.isInstanceOf(OidcUserAuthority.class)
|
||||
.hasToString("OIDC_USER");
|
||||
SecurityAssertions.assertThat(authentication).hasAuthority("OIDC_USER").isInstanceOf(OidcUserAuthority.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -593,9 +581,7 @@ public class OAuth2LoginConfigurerTests {
|
|||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(1);
|
||||
assertThat(authentication.getAuthorities()).first()
|
||||
.isInstanceOf(OidcUserAuthority.class)
|
||||
.hasToString("OIDC_USER");
|
||||
SecurityAssertions.assertThat(authentication).hasAuthority("OIDC_USER").isInstanceOf(OidcUserAuthority.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -614,9 +600,7 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(2);
|
||||
assertThat(authentication.getAuthorities()).first().hasToString("OIDC_USER");
|
||||
assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OIDC_USER");
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("OIDC_USER", "ROLE_OIDC_USER");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -635,9 +619,7 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(2);
|
||||
assertThat(authentication.getAuthorities()).first().hasToString("OIDC_USER");
|
||||
assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OIDC_USER");
|
||||
SecurityAssertions.assertThat(authentication).hasAuthorities("OIDC_USER", "ROLE_OIDC_USER");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -690,11 +672,7 @@ public class OAuth2LoginConfigurerTests {
|
|||
Authentication authentication = this.securityContextRepository
|
||||
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
|
||||
.getAuthentication();
|
||||
assertThat(authentication.getAuthorities()).hasSize(1);
|
||||
assertThat(authentication.getAuthorities()).first()
|
||||
.isInstanceOf(OidcUserAuthority.class)
|
||||
.hasToString("OIDC_USER");
|
||||
|
||||
SecurityAssertions.assertThat(authentication).hasAuthority("OIDC_USER").isInstanceOf(OidcUserAuthority.class);
|
||||
// Ensure shared objects set for OAuth2 Client are not used
|
||||
ClientRegistrationRepository clientRegistrationRepository = this.spring.getContext()
|
||||
.getBean(ClientRegistrationRepository.class);
|
||||
|
|
|
@ -2674,6 +2674,7 @@ public class OAuth2ResourceServerConfigurerTests {
|
|||
String requiresReadScope(JwtAuthenticationToken token) {
|
||||
return token.getAuthorities()
|
||||
.stream()
|
||||
.filter((ga) -> ga.getAuthority().startsWith("SCOPE_"))
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.collect(Collectors.toList())
|
||||
.toString();
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2004-present 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.security.authentication;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.assertj.core.api.AbstractObjectAssert;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.api.CollectionAssert;
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.assertj.core.api.ObjectAssert;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
|
||||
@NullMarked
|
||||
public final class SecurityAssertions {
|
||||
|
||||
private SecurityAssertions() {
|
||||
|
||||
}
|
||||
|
||||
public static AuthenticationAssert assertThat(@Nullable Authentication authentication) {
|
||||
Assertions.assertThat(authentication).isNotNull();
|
||||
return new AuthenticationAssert(authentication);
|
||||
}
|
||||
|
||||
public static final class AuthenticationAssert extends AbstractObjectAssert<AuthenticationAssert, Authentication> {
|
||||
|
||||
private final Authentication authentication;
|
||||
|
||||
private AuthenticationAssert(Authentication authentication) {
|
||||
super(authentication, AuthenticationAssert.class);
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
||||
public AuthenticationAssert name(String name) {
|
||||
Assertions.assertThat(this.authentication.getName()).isEqualTo(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ObjectAssert<GrantedAuthority> hasAuthority(String authority) {
|
||||
Collection<? extends GrantedAuthority> actual = this.authentication.getAuthorities();
|
||||
for (GrantedAuthority element : actual) {
|
||||
if (element.getAuthority().equals(authority)) {
|
||||
return new ObjectAssert<>(element);
|
||||
}
|
||||
}
|
||||
throw new AssertionError(actual + " does not contain " + authority + " as expected");
|
||||
}
|
||||
|
||||
public CollectionAssert<GrantedAuthority> hasAuthorities(String... authorities) {
|
||||
HasAuthoritiesPredicate test = new HasAuthoritiesPredicate(authorities);
|
||||
return authorities().has(new Condition<>(test, "contains %s", Arrays.toString(authorities)));
|
||||
}
|
||||
|
||||
public CollectionAssert<GrantedAuthority> authorities() {
|
||||
return new CollectionAssert<>(this.authentication.getAuthorities());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class HasAuthoritiesPredicate implements Predicate<Collection<? extends GrantedAuthority>> {
|
||||
|
||||
private final Collection<String> expected;
|
||||
|
||||
private HasAuthoritiesPredicate(String... expected) {
|
||||
this.expected = List.of(expected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Collection<? extends GrantedAuthority> actual) {
|
||||
Set<String> asString = AuthorityUtils.authorityListToSet(actual);
|
||||
return asString.containsAll(this.expected);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -19,7 +19,8 @@ dependencies {
|
|||
exclude(group: 'org.springframework.data', module: 'spring-data-commons')
|
||||
}
|
||||
|
||||
testImplementation project(':spring-security-test')
|
||||
testImplementation project(path : ':spring-security-core', configuration : 'tests')
|
||||
testImplementation project(":spring-security-test")
|
||||
testImplementation 'org.slf4j:slf4j-api'
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.springframework.security.authentication.CredentialsExpiredException;
|
|||
import org.springframework.security.authentication.DisabledException;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.authentication.LockedException;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.ContextFactory;
|
||||
|
@ -357,10 +358,10 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
|
|||
.willReturn(new MockNamingEnumeration(sr));
|
||||
provider.contextFactory = createContextFactoryReturning(this.ctx);
|
||||
Authentication result = provider.authenticate(this.joe);
|
||||
assertThat(result.getAuthorities()).isEmpty();
|
||||
SecurityAssertions.assertThat(result).authorities().doesNotHaveToString("Admin");
|
||||
dca.addAttributeValue("memberOf", "CN=Admin,CN=Users,DC=mydomain,DC=eu");
|
||||
result = provider.authenticate(this.joe);
|
||||
assertThat(result.getAuthorities()).hasSize(1);
|
||||
SecurityAssertions.assertThat(result).hasAuthority("Admin");
|
||||
}
|
||||
|
||||
static class MockNamingEnumeration implements NamingEnumeration<SearchResult> {
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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_");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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_");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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_");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ import org.opensaml.xmlsec.encryption.impl.EncryptedDataBuilder;
|
|||
import org.opensaml.xmlsec.signature.support.SignatureConstants;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
|
@ -734,7 +735,7 @@ public class OpenSaml5AuthenticationProviderTests {
|
|||
Response response = TestOpenSamlObjects.signedResponseWithOneAssertion();
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
Authentication authentication = provider.authenticate(token);
|
||||
assertThat(AuthorityUtils.authorityListToSet(authentication.getAuthorities())).containsExactly("CUSTOM");
|
||||
SecurityAssertions.assertThat(authentication).hasAuthority("CUSTOM");
|
||||
verify(grantedAuthoritiesConverter).convert(any());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue