9 changed files with 563 additions and 17 deletions
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
/* |
||||
* Copyright 2020 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.oauth2.server.authorization; |
||||
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken; |
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; |
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; |
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; |
||||
|
||||
import java.time.Instant; |
||||
|
||||
/** |
||||
* @author Joe Grandja |
||||
*/ |
||||
public class TestOAuth2Authorizations { |
||||
|
||||
public static OAuth2Authorization.Builder authorization() { |
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); |
||||
OAuth2AccessToken accessToken = new OAuth2AccessToken( |
||||
OAuth2AccessToken.TokenType.BEARER, "access-token", Instant.now(), Instant.now().plusSeconds(300)); |
||||
OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode() |
||||
.authorizationUri("https://provider.com/oauth2/authorize") |
||||
.clientId(registeredClient.getClientId()) |
||||
.redirectUri("https://client.com/authorized") |
||||
.state("state") |
||||
.build(); |
||||
return OAuth2Authorization.withRegisteredClient(registeredClient) |
||||
.principalName("principal") |
||||
.accessToken(accessToken) |
||||
.attribute(OAuth2AuthorizationAttributeNames.CODE, "code") |
||||
.attribute(OAuth2AuthorizationAttributeNames.AUTHORIZATION_REQUEST, authorizationRequest); |
||||
} |
||||
} |
||||
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
/* |
||||
* Copyright 2020 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.oauth2.server.authorization.authentication; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken; |
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; |
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; |
||||
|
||||
import java.time.Instant; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
/** |
||||
* Tests for {@link OAuth2AccessTokenAuthenticationToken}. |
||||
* |
||||
* @author Joe Grandja |
||||
*/ |
||||
public class OAuth2AccessTokenAuthenticationTokenTests { |
||||
private RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); |
||||
private OAuth2ClientAuthenticationToken clientPrincipal = |
||||
new OAuth2ClientAuthenticationToken(this.registeredClient); |
||||
private OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, |
||||
"access-token", Instant.now(), Instant.now().plusSeconds(300)); |
||||
|
||||
@Test |
||||
public void constructorWhenRegisteredClientNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> new OAuth2AccessTokenAuthenticationToken(null, this.clientPrincipal, this.accessToken)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("registeredClient cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenClientPrincipalNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> new OAuth2AccessTokenAuthenticationToken(this.registeredClient, null, this.accessToken)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("clientPrincipal cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenAccessTokenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> new OAuth2AccessTokenAuthenticationToken(this.registeredClient, this.clientPrincipal, null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("accessToken cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenAllValuesProvidedThenCreated() { |
||||
OAuth2AccessTokenAuthenticationToken authentication = new OAuth2AccessTokenAuthenticationToken( |
||||
this.registeredClient, this.clientPrincipal, this.accessToken); |
||||
assertThat(authentication.getPrincipal()).isEqualTo(this.clientPrincipal); |
||||
assertThat(authentication.getCredentials().toString()).isEmpty(); |
||||
assertThat(authentication.getRegisteredClient()).isEqualTo(this.registeredClient); |
||||
assertThat(authentication.getAccessToken()).isEqualTo(this.accessToken); |
||||
} |
||||
} |
||||
@ -0,0 +1,178 @@
@@ -0,0 +1,178 @@
|
||||
/* |
||||
* Copyright 2020 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.oauth2.server.authorization.authentication; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.mockito.ArgumentCaptor; |
||||
import org.springframework.security.authentication.TestingAuthenticationToken; |
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; |
||||
import org.springframework.security.oauth2.core.OAuth2ErrorCodes; |
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; |
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; |
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationAttributeNames; |
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; |
||||
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations; |
||||
import org.springframework.security.oauth2.server.authorization.TokenType; |
||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; |
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; |
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; |
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
import static org.mockito.ArgumentMatchers.eq; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
/** |
||||
* Tests for {@link OAuth2AuthorizationCodeAuthenticationProvider}. |
||||
* |
||||
* @author Joe Grandja |
||||
*/ |
||||
public class OAuth2AuthorizationCodeAuthenticationProviderTests { |
||||
private RegisteredClient registeredClient; |
||||
private RegisteredClientRepository registeredClientRepository; |
||||
private OAuth2AuthorizationService authorizationService; |
||||
private OAuth2AuthorizationCodeAuthenticationProvider authenticationProvider; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
this.registeredClient = TestRegisteredClients.registeredClient().build(); |
||||
this.registeredClientRepository = new InMemoryRegisteredClientRepository(this.registeredClient); |
||||
this.authorizationService = mock(OAuth2AuthorizationService.class); |
||||
this.authenticationProvider = new OAuth2AuthorizationCodeAuthenticationProvider( |
||||
this.registeredClientRepository, this.authorizationService); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenRegisteredClientRepositoryNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> new OAuth2AuthorizationCodeAuthenticationProvider(null, this.authorizationService)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("registeredClientRepository cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenAuthorizationServiceNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> new OAuth2AuthorizationCodeAuthenticationProvider(this.registeredClientRepository, null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("authorizationService cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void supportsWhenTypeOAuth2AuthorizationCodeAuthenticationTokenThenReturnTrue() { |
||||
assertThat(this.authenticationProvider.supports(OAuth2AuthorizationCodeAuthenticationToken.class)).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
public void authenticateWhenClientPrincipalNotOAuth2ClientAuthenticationTokenThenThrowOAuth2AuthenticationException() { |
||||
TestingAuthenticationToken clientPrincipal = new TestingAuthenticationToken( |
||||
this.registeredClient.getClientId(), this.registeredClient.getClientSecret()); |
||||
OAuth2AuthorizationCodeAuthenticationToken authentication = |
||||
new OAuth2AuthorizationCodeAuthenticationToken("code", clientPrincipal, null); |
||||
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication)) |
||||
.isInstanceOf(OAuth2AuthenticationException.class) |
||||
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError()) |
||||
.extracting("errorCode") |
||||
.isEqualTo(OAuth2ErrorCodes.INVALID_CLIENT); |
||||
} |
||||
|
||||
@Test |
||||
public void authenticateWhenClientPrincipalNotAuthenticatedThenThrowOAuth2AuthenticationException() { |
||||
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( |
||||
this.registeredClient.getClientId(), this.registeredClient.getClientSecret()); |
||||
OAuth2AuthorizationCodeAuthenticationToken authentication = |
||||
new OAuth2AuthorizationCodeAuthenticationToken("code", clientPrincipal, null); |
||||
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication)) |
||||
.isInstanceOf(OAuth2AuthenticationException.class) |
||||
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError()) |
||||
.extracting("errorCode") |
||||
.isEqualTo(OAuth2ErrorCodes.INVALID_CLIENT); |
||||
} |
||||
|
||||
@Test |
||||
public void authenticateWhenInvalidCodeThenThrowOAuth2AuthenticationException() { |
||||
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(this.registeredClient); |
||||
OAuth2AuthorizationCodeAuthenticationToken authentication = |
||||
new OAuth2AuthorizationCodeAuthenticationToken("code", clientPrincipal, null); |
||||
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication)) |
||||
.isInstanceOf(OAuth2AuthenticationException.class) |
||||
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError()) |
||||
.extracting("errorCode") |
||||
.isEqualTo(OAuth2ErrorCodes.INVALID_GRANT); |
||||
} |
||||
|
||||
@Test |
||||
public void authenticateWhenCodeIssuedToAnotherClientThenThrowOAuth2AuthenticationException() { |
||||
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization().build(); |
||||
when(this.authorizationService.findByTokenAndTokenType(eq("code"), eq(TokenType.AUTHORIZATION_CODE))) |
||||
.thenReturn(authorization); |
||||
|
||||
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( |
||||
TestRegisteredClients.registeredClient2().build()); |
||||
OAuth2AuthorizationCodeAuthenticationToken authentication = |
||||
new OAuth2AuthorizationCodeAuthenticationToken("code", clientPrincipal, null); |
||||
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication)) |
||||
.isInstanceOf(OAuth2AuthenticationException.class) |
||||
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError()) |
||||
.extracting("errorCode") |
||||
.isEqualTo(OAuth2ErrorCodes.INVALID_GRANT); |
||||
} |
||||
|
||||
@Test |
||||
public void authenticateWhenInvalidRedirectUriThenThrowOAuth2AuthenticationException() { |
||||
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization().build(); |
||||
when(this.authorizationService.findByTokenAndTokenType(eq("code"), eq(TokenType.AUTHORIZATION_CODE))) |
||||
.thenReturn(authorization); |
||||
|
||||
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(this.registeredClient); |
||||
OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute( |
||||
OAuth2AuthorizationAttributeNames.AUTHORIZATION_REQUEST); |
||||
OAuth2AuthorizationCodeAuthenticationToken authentication = |
||||
new OAuth2AuthorizationCodeAuthenticationToken("code", clientPrincipal, authorizationRequest.getRedirectUri() + "-invalid"); |
||||
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication)) |
||||
.isInstanceOf(OAuth2AuthenticationException.class) |
||||
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError()) |
||||
.extracting("errorCode") |
||||
.isEqualTo(OAuth2ErrorCodes.INVALID_GRANT); |
||||
} |
||||
|
||||
@Test |
||||
public void authenticateWhenValidCodeThenReturnAccessToken() { |
||||
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization().build(); |
||||
when(this.authorizationService.findByTokenAndTokenType(eq("code"), eq(TokenType.AUTHORIZATION_CODE))) |
||||
.thenReturn(authorization); |
||||
|
||||
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(this.registeredClient); |
||||
OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute( |
||||
OAuth2AuthorizationAttributeNames.AUTHORIZATION_REQUEST); |
||||
OAuth2AuthorizationCodeAuthenticationToken authentication = |
||||
new OAuth2AuthorizationCodeAuthenticationToken("code", clientPrincipal, authorizationRequest.getRedirectUri()); |
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = |
||||
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication); |
||||
|
||||
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class); |
||||
verify(this.authorizationService).save(authorizationCaptor.capture()); |
||||
OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue(); |
||||
|
||||
assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId()); |
||||
assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal); |
||||
assertThat(updatedAuthorization.getAccessToken()).isNotNull(); |
||||
assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken()); |
||||
} |
||||
} |
||||
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
/* |
||||
* Copyright 2020 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.oauth2.server.authorization.authentication; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
/** |
||||
* Tests for {@link OAuth2AuthorizationCodeAuthenticationToken}. |
||||
* |
||||
* @author Joe Grandja |
||||
*/ |
||||
public class OAuth2AuthorizationCodeAuthenticationTokenTests { |
||||
private String code = "code"; |
||||
private OAuth2ClientAuthenticationToken clientPrincipal = |
||||
new OAuth2ClientAuthenticationToken(TestRegisteredClients.registeredClient().build()); |
||||
private String clientId = "clientId"; |
||||
private String redirectUri = "redirectUri"; |
||||
|
||||
@Test |
||||
public void constructorWhenCodeNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> new OAuth2AuthorizationCodeAuthenticationToken(null, this.clientPrincipal, this.redirectUri)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("code cannot be empty"); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenClientPrincipalNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> new OAuth2AuthorizationCodeAuthenticationToken(this.code, (Authentication) null, this.redirectUri)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("clientPrincipal cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenClientIdNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> new OAuth2AuthorizationCodeAuthenticationToken(this.code, (String) null, this.redirectUri)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("clientId cannot be empty"); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenClientPrincipalProvidedThenCreated() { |
||||
OAuth2AuthorizationCodeAuthenticationToken authentication = new OAuth2AuthorizationCodeAuthenticationToken( |
||||
this.code, this.clientPrincipal, this.redirectUri); |
||||
assertThat(authentication.getPrincipal()).isEqualTo(this.clientPrincipal); |
||||
assertThat(authentication.getCredentials().toString()).isEmpty(); |
||||
assertThat(authentication.getCode()).isEqualTo(this.code); |
||||
assertThat(authentication.getRedirectUri()).isEqualTo(this.redirectUri); |
||||
} |
||||
|
||||
@Test |
||||
public void constructorWhenClientIdProvidedThenCreated() { |
||||
OAuth2AuthorizationCodeAuthenticationToken authentication = new OAuth2AuthorizationCodeAuthenticationToken( |
||||
this.code, this.clientId, this.redirectUri); |
||||
assertThat(authentication.getPrincipal()).isEqualTo(this.clientId); |
||||
assertThat(authentication.getCredentials().toString()).isEmpty(); |
||||
assertThat(authentication.getCode()).isEqualTo(this.code); |
||||
assertThat(authentication.getRedirectUri()).isEqualTo(this.redirectUri); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue