Skip to content

Commit 758b35d

Browse files
committed
Add Factor Tests for Authentication Providers
Issue spring-projectsgh-17933
1 parent 39e2bb6 commit 758b35d

File tree

9 files changed

+158
-0
lines changed

9 files changed

+158
-0
lines changed

core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.security.authentication.DisabledException;
3232
import org.springframework.security.authentication.InternalAuthenticationServiceException;
3333
import org.springframework.security.authentication.LockedException;
34+
import org.springframework.security.authentication.SecurityAssertions;
3435
import org.springframework.security.authentication.TestingAuthenticationToken;
3536
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
3637
import org.springframework.security.authentication.password.CompromisedPasswordChecker;
@@ -504,6 +505,15 @@ void authenticateWhenPasswordNotLeakedThenNoException() {
504505
assertThat(authentication).isNotNull();
505506
}
506507

508+
@Test
509+
void authenticateWhenSuccessThenIssuesFactor() {
510+
UserDetails user = PasswordEncodedUser.user();
511+
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(withUsers(user));
512+
Authentication request = new UsernamePasswordAuthenticationToken("user", "password");
513+
Authentication result = provider.authenticate(request);
514+
SecurityAssertions.assertThat(result).hasAuthority("FACTOR_PASSWORD");
515+
}
516+
507517
private UserDetailsService withUsers(UserDetails... users) {
508518
return new InMemoryUserDetailsManager(users);
509519
}

core/src/test/java/org/springframework/security/authentication/ott/OneTimeTokenAuthenticationProviderTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.mockito.junit.jupiter.MockitoExtension;
2727

2828
import org.springframework.security.authentication.BadCredentialsException;
29+
import org.springframework.security.authentication.SecurityAssertions;
2930
import org.springframework.security.core.Authentication;
3031
import org.springframework.security.core.userdetails.User;
3132
import org.springframework.security.core.userdetails.UserDetailsService;
@@ -98,6 +99,18 @@ void authenticateWhenUserIsNotFoundThenFails() {
9899
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(token));
99100
}
100101

102+
@Test
103+
void authenticateWhenSuccessThenIssuesFactor() {
104+
given(this.oneTimeTokenService.consume(any()))
105+
.willReturn(new DefaultOneTimeToken(TOKEN, USERNAME, Instant.now().plusSeconds(120)));
106+
given(this.userDetailsService.loadUserByUsername(anyString()))
107+
.willReturn(new User(USERNAME, PASSWORD, List.of()));
108+
OneTimeTokenAuthenticationToken token = new OneTimeTokenAuthenticationToken(TOKEN);
109+
110+
Authentication authentication = this.provider.authenticate(token);
111+
SecurityAssertions.assertThat(authentication).hasAuthority("FACTOR_OTT");
112+
}
113+
101114
@Test
102115
void constructorWhenOneTimeTokenServiceIsNullThenThrowIllegalArgumentException() {
103116
// @formatter:off

ldap/src/test/java/org/springframework/security/ldap/authentication/LdapAuthenticationProviderTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.ldap.support.LdapNameBuilder;
2727
import org.springframework.security.authentication.BadCredentialsException;
2828
import org.springframework.security.authentication.InternalAuthenticationServiceException;
29+
import org.springframework.security.authentication.SecurityAssertions;
2930
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
3031
import org.springframework.security.core.Authentication;
3132
import org.springframework.security.core.GrantedAuthority;
@@ -156,6 +157,16 @@ public void authenticateWithNamingException() {
156157
.isSameAs(expectedCause);
157158
}
158159

160+
@Test
161+
void authenticateWhenSuccessThenIssuesFactor() {
162+
MockAuthenticator authenticator = new MockAuthenticator();
163+
MockAuthoritiesPopulator populator = new MockAuthoritiesPopulator();
164+
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(authenticator, populator);
165+
UsernamePasswordAuthenticationToken request = new UsernamePasswordAuthenticationToken("ben", "benspassword");
166+
Authentication result = ldapProvider.authenticate(request);
167+
SecurityAssertions.assertThat(result).hasAuthority("FACTOR_PASSWORD");
168+
}
169+
159170
class MockAuthenticator implements LdapAuthenticator {
160171

161172
@Override

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/authentication/OAuth2LoginAuthenticationProviderTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import org.mockito.ArgumentCaptor;
3030
import org.mockito.stubbing.Answer;
3131

32+
import org.springframework.security.authentication.SecurityAssertions;
33+
import org.springframework.security.core.Authentication;
3234
import org.springframework.security.core.GrantedAuthority;
3335
import org.springframework.security.core.authority.AuthorityUtils;
3436
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
@@ -48,6 +50,7 @@
4850
import org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationRequests;
4951
import org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationResponses;
5052
import org.springframework.security.oauth2.core.user.OAuth2User;
53+
import org.springframework.security.oauth2.core.user.TestOAuth2Users;
5154

5255
import static org.assertj.core.api.Assertions.assertThat;
5356
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -206,6 +209,17 @@ public void authenticateWhenTokenSuccessResponseThenAdditionalParametersAddedToU
206209
.containsAllEntriesOf(accessTokenResponse.getAdditionalParameters());
207210
}
208211

212+
@Test
213+
public void authenticateWhenLoginSuccessThenIssuesFactor() {
214+
OAuth2AccessTokenResponse accessTokenResponse = accessTokenSuccessResponse();
215+
given(this.accessTokenResponseClient.getTokenResponse(any())).willReturn(accessTokenResponse);
216+
given(this.userService.loadUser(any())).willReturn(TestOAuth2Users.create());
217+
Authentication request = new OAuth2LoginAuthenticationToken(this.clientRegistration,
218+
this.authorizationExchange);
219+
Authentication result = this.authenticationProvider.authenticate(request);
220+
SecurityAssertions.assertThat(result).hasAuthority("FACTOR_AUTHORIZATION_CODE");
221+
}
222+
209223
private OAuth2AccessTokenResponse accessTokenSuccessResponse() {
210224
Instant expiresAt = Instant.now().plusSeconds(5);
211225
Set<String> scopes = new LinkedHashSet<>(Arrays.asList("scope1", "scope2"));

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationConverterTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.core.convert.converter.Converter;
2525
import org.springframework.security.authentication.AbstractAuthenticationToken;
2626
import org.springframework.security.authentication.SecurityAssertions;
27+
import org.springframework.security.core.Authentication;
2728
import org.springframework.security.core.GrantedAuthority;
2829
import org.springframework.security.core.authority.SimpleGrantedAuthority;
2930
import org.springframework.security.oauth2.jwt.Jwt;
@@ -110,4 +111,11 @@ public void convertWhenPrincipalClaimNameSetAndClaimValueIsNotString() {
110111
assertThat(authentication.getName()).isEqualTo("100");
111112
}
112113

114+
@Test
115+
public void convertWhenDefaultsThenIssuesFactor() {
116+
Jwt jwt = TestJwts.jwt().build();
117+
Authentication result = this.jwtAuthenticationConverter.convert(jwt);
118+
SecurityAssertions.assertThat(result).hasAuthority("FACTOR_BEARER");
119+
}
120+
113121
}

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,17 @@ public void authenticateWhenCustomAuthenticationConverterThenUses() {
146146
verifyNoMoreInteractions(introspector, authenticationConverter);
147147
}
148148

149+
@Test
150+
void authenticateWhenSuccessThenIssuesFactor() {
151+
OAuth2AuthenticatedPrincipal principal = TestOAuth2AuthenticatedPrincipals.active();
152+
OpaqueTokenIntrospector introspector = mock(OpaqueTokenIntrospector.class);
153+
given(introspector.introspect(any())).willReturn(principal);
154+
OpaqueTokenAuthenticationProvider provider = new OpaqueTokenAuthenticationProvider(introspector);
155+
Authentication request = new BearerTokenAuthenticationToken("token");
156+
Authentication result = provider.authenticate(request);
157+
SecurityAssertions.assertThat(result).hasAuthority("FACTOR_BEARER");
158+
}
159+
149160
static Predicate<GrantedAuthority> isScope() {
150161
return (a) -> a.getAuthority().startsWith("SCOPE_");
151162
}

saml2/saml2-service-provider/src/opensaml5Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml5AuthenticationProviderTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,14 @@ public void authenticateWhenNullIssuerThenNoNullPointer() {
985985
assertThatExceptionOfType(Saml2AuthenticationException.class).isThrownBy(() -> provider.authenticate(token));
986986
}
987987

988+
@Test
989+
public void authenticateWhenSuccessThenIssuesFactor() {
990+
Response response = TestOpenSamlObjects.signedResponseWithOneAssertion();
991+
Authentication request = token(response, verifying(registration()));
992+
Authentication result = this.provider.authenticate(request);
993+
SecurityAssertions.assertThat(result).hasAuthority("FACTOR_SAML_RESPONSE");
994+
}
995+
988996
private <T extends XMLObject> T build(QName qName) {
989997
return (T) XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(qName).buildObject(qName);
990998
}

web/src/test/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedAuthenticationProviderTests.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,28 @@
1616

1717
package org.springframework.security.web.authentication.preauth;
1818

19+
import java.util.Collection;
20+
import java.util.function.Supplier;
21+
1922
import org.junit.jupiter.api.Test;
2023

24+
import org.springframework.security.authentication.SecurityAssertions;
2125
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
2226
import org.springframework.security.core.Authentication;
27+
import org.springframework.security.core.GrantedAuthority;
2328
import org.springframework.security.core.authority.AuthorityUtils;
2429
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
30+
import org.springframework.security.core.userdetails.PasswordEncodedUser;
2531
import org.springframework.security.core.userdetails.User;
2632
import org.springframework.security.core.userdetails.UserDetails;
2733
import org.springframework.security.core.userdetails.UsernameNotFoundException;
2834

2935
import static org.assertj.core.api.Assertions.assertThat;
3036
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
3137
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
38+
import static org.mockito.BDDMockito.given;
39+
import static org.mockito.Mockito.mock;
40+
import static org.mockito.Mockito.verify;
3241

3342
/**
3443
* @author TSARDD
@@ -89,6 +98,19 @@ public final void authenticateUnknownUserThrowsException() throws Exception {
8998
assertThatExceptionOfType(UsernameNotFoundException.class).isThrownBy(() -> provider.authenticate(request));
9099
}
91100

101+
@Test
102+
void authenticateWhenSuccessThenIssuesFactor() {
103+
UserDetails ud = PasswordEncodedUser.user();
104+
PreAuthenticatedAuthenticationProvider provider = getProvider(ud);
105+
Supplier<Collection<GrantedAuthority>> authorities = mock(Supplier.class);
106+
given(authorities.get()).willReturn(AuthorityUtils.createAuthorityList("FACTOR"));
107+
provider.setGrantedAuthoritySupplier(authorities);
108+
Authentication request = new PreAuthenticatedAuthenticationToken(ud.getUsername(), ud.getPassword());
109+
Authentication result = provider.authenticate(request);
110+
SecurityAssertions.assertThat(result).hasAuthority("FACTOR");
111+
verify(authorities).get();
112+
}
113+
92114
@Test
93115
public final void supportsArbitraryObject() throws Exception {
94116
PreAuthenticatedAuthenticationProvider provider = getProvider(null);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2004-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.web.webauthn.authentication;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.security.authentication.SecurityAssertions;
22+
import org.springframework.security.core.Authentication;
23+
import org.springframework.security.core.userdetails.PasswordEncodedUser;
24+
import org.springframework.security.core.userdetails.UserDetailsService;
25+
import org.springframework.security.web.webauthn.api.AuthenticatorAssertionResponse;
26+
import org.springframework.security.web.webauthn.api.PublicKeyCredential;
27+
import org.springframework.security.web.webauthn.api.PublicKeyCredentialRequestOptions;
28+
import org.springframework.security.web.webauthn.api.TestAuthenticationAssertionResponses;
29+
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialRequestOptions;
30+
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialUserEntities;
31+
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentials;
32+
import org.springframework.security.web.webauthn.management.RelyingPartyAuthenticationRequest;
33+
import org.springframework.security.web.webauthn.management.WebAuthnRelyingPartyOperations;
34+
35+
import static org.mockito.ArgumentMatchers.any;
36+
import static org.mockito.BDDMockito.given;
37+
import static org.mockito.Mockito.mock;
38+
39+
class WebAuthnAuthenticationProviderTests {
40+
41+
@Test
42+
void authenticateWhenSuccessThenIssuesFactor() {
43+
WebAuthnRelyingPartyOperations operations = mock(WebAuthnRelyingPartyOperations.class);
44+
UserDetailsService users = mock(UserDetailsService.class);
45+
PublicKeyCredentialRequestOptions options = TestPublicKeyCredentialRequestOptions.create().build();
46+
AuthenticatorAssertionResponse response = TestAuthenticationAssertionResponses
47+
.createAuthenticatorAssertionResponse()
48+
.build();
49+
PublicKeyCredential<AuthenticatorAssertionResponse> credentials = TestPublicKeyCredentials
50+
.createPublicKeyCredential(response)
51+
.build();
52+
Authentication request = new WebAuthnAuthenticationRequestToken(
53+
new RelyingPartyAuthenticationRequest(options, credentials));
54+
WebAuthnAuthenticationProvider provider = new WebAuthnAuthenticationProvider(operations, users);
55+
given(users.loadUserByUsername(any())).willReturn(PasswordEncodedUser.user());
56+
given(operations.authenticate(any())).willReturn(TestPublicKeyCredentialUserEntities.userEntity().build());
57+
Authentication result = provider.authenticate(request);
58+
SecurityAssertions.assertThat(result).hasAuthority("FACTOR_WEBAUTHN");
59+
}
60+
61+
}

0 commit comments

Comments
 (0)