mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	Associate Refresh Token to OAuth2AuthorizedClient
Fixes gh-5416
This commit is contained in:
		
							parent
							
								
									1137f3b46d
								
							
						
					
					
						commit
						02d29887fb
					
				| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -15,8 +15,10 @@ | ||||
|  */ | ||||
| package org.springframework.security.oauth2.client; | ||||
| 
 | ||||
| import org.springframework.lang.Nullable; | ||||
| import org.springframework.security.oauth2.client.registration.ClientRegistration; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| /** | ||||
| @ -33,11 +35,13 @@ import org.springframework.util.Assert; | ||||
|  * @since 5.0 | ||||
|  * @see ClientRegistration | ||||
|  * @see OAuth2AccessToken | ||||
|  * @see OAuth2RefreshToken | ||||
|  */ | ||||
| public class OAuth2AuthorizedClient { | ||||
| 	private final ClientRegistration clientRegistration; | ||||
| 	private final String principalName; | ||||
| 	private final OAuth2AccessToken accessToken; | ||||
| 	private final OAuth2RefreshToken refreshToken; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Constructs an {@code OAuth2AuthorizedClient} using the provided parameters. | ||||
| @ -47,12 +51,26 @@ public class OAuth2AuthorizedClient { | ||||
| 	 * @param accessToken the access token credential granted | ||||
| 	 */ | ||||
| 	public OAuth2AuthorizedClient(ClientRegistration clientRegistration, String principalName, OAuth2AccessToken accessToken) { | ||||
| 		this(clientRegistration, principalName, accessToken, null); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Constructs an {@code OAuth2AuthorizedClient} using the provided parameters. | ||||
| 	 * | ||||
| 	 * @param clientRegistration the authorized client's registration | ||||
| 	 * @param principalName the name of the End-User {@code Principal} (Resource Owner) | ||||
| 	 * @param accessToken the access token credential granted | ||||
| 	 * @param refreshToken the refresh token credential granted | ||||
| 	 */ | ||||
| 	public OAuth2AuthorizedClient(ClientRegistration clientRegistration, String principalName, | ||||
| 									OAuth2AccessToken accessToken, @Nullable OAuth2RefreshToken refreshToken) { | ||||
| 		Assert.notNull(clientRegistration, "clientRegistration cannot be null"); | ||||
| 		Assert.hasText(principalName, "principalName cannot be empty"); | ||||
| 		Assert.notNull(accessToken, "accessToken cannot be null"); | ||||
| 		this.clientRegistration = clientRegistration; | ||||
| 		this.principalName = principalName; | ||||
| 		this.accessToken = accessToken; | ||||
| 		this.refreshToken = refreshToken; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| @ -81,4 +99,14 @@ public class OAuth2AuthorizedClient { | ||||
| 	public OAuth2AccessToken getAccessToken() { | ||||
| 		return this.accessToken; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Returns the {@link OAuth2RefreshToken refresh token} credential granted. | ||||
| 	 * | ||||
| 	 * @since 5.1 | ||||
| 	 * @return the {@link OAuth2RefreshToken} | ||||
| 	 */ | ||||
| 	public @Nullable OAuth2RefreshToken getRefreshToken() { | ||||
| 		return this.refreshToken; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -20,7 +20,6 @@ import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.AuthenticationException; | ||||
| import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient; | ||||
| import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| @ -69,13 +68,12 @@ public class OAuth2AuthorizationCodeAuthenticationProvider implements Authentica | ||||
| 					authorizationCodeAuthentication.getClientRegistration(), | ||||
| 					authorizationCodeAuthentication.getAuthorizationExchange())); | ||||
| 
 | ||||
| 		OAuth2AccessToken accessToken = accessTokenResponse.getAccessToken(); | ||||
| 
 | ||||
| 		OAuth2AuthorizationCodeAuthenticationToken authenticationResult = | ||||
| 			new OAuth2AuthorizationCodeAuthenticationToken( | ||||
| 				authorizationCodeAuthentication.getClientRegistration(), | ||||
| 				authorizationCodeAuthentication.getAuthorizationExchange(), | ||||
| 				accessToken); | ||||
| 				accessTokenResponse.getAccessToken(), | ||||
| 				accessTokenResponse.getRefreshToken()); | ||||
| 		authenticationResult.setDetails(authorizationCodeAuthentication.getDetails()); | ||||
| 
 | ||||
| 		return authenticationResult; | ||||
|  | ||||
| @ -15,10 +15,12 @@ | ||||
|  */ | ||||
| package org.springframework.security.oauth2.client.authentication; | ||||
| 
 | ||||
| import org.springframework.lang.Nullable; | ||||
| import org.springframework.security.authentication.AbstractAuthenticationToken; | ||||
| import org.springframework.security.core.SpringSecurityCoreVersion; | ||||
| import org.springframework.security.oauth2.client.registration.ClientRegistration; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| @ -40,6 +42,7 @@ public class OAuth2AuthorizationCodeAuthenticationToken extends AbstractAuthenti | ||||
| 	private ClientRegistration clientRegistration; | ||||
| 	private OAuth2AuthorizationExchange authorizationExchange; | ||||
| 	private OAuth2AccessToken accessToken; | ||||
| 	private OAuth2RefreshToken refreshToken; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This constructor should be used when the Authorization Request/Response is complete. | ||||
| @ -67,9 +70,26 @@ public class OAuth2AuthorizationCodeAuthenticationToken extends AbstractAuthenti | ||||
| 	public OAuth2AuthorizationCodeAuthenticationToken(ClientRegistration clientRegistration, | ||||
| 														OAuth2AuthorizationExchange authorizationExchange, | ||||
| 														OAuth2AccessToken accessToken) { | ||||
| 		this(clientRegistration, authorizationExchange, accessToken, null); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This constructor should be used when the Access Token Request/Response is complete, | ||||
| 	 * which indicates that the Authorization Code Grant flow has fully completed. | ||||
| 	 * | ||||
| 	 * @param clientRegistration the client registration | ||||
| 	 * @param authorizationExchange the authorization exchange | ||||
| 	 * @param accessToken the access token credential | ||||
| 	 * @param refreshToken the refresh token credential | ||||
| 	 */ | ||||
| 	public OAuth2AuthorizationCodeAuthenticationToken(ClientRegistration clientRegistration, | ||||
| 														OAuth2AuthorizationExchange authorizationExchange, | ||||
| 														OAuth2AccessToken accessToken, | ||||
| 														@Nullable OAuth2RefreshToken refreshToken) { | ||||
| 		this(clientRegistration, authorizationExchange); | ||||
| 		Assert.notNull(accessToken, "accessToken cannot be null"); | ||||
| 		this.accessToken = accessToken; | ||||
| 		this.refreshToken = refreshToken; | ||||
| 		this.setAuthenticated(true); | ||||
| 	} | ||||
| 
 | ||||
| @ -111,4 +131,13 @@ public class OAuth2AuthorizationCodeAuthenticationToken extends AbstractAuthenti | ||||
| 	public OAuth2AccessToken getAccessToken() { | ||||
| 		return this.accessToken; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Returns the {@link OAuth2RefreshToken refresh token}. | ||||
| 	 * | ||||
| 	 * @return the {@link OAuth2RefreshToken} | ||||
| 	 */ | ||||
| 	public @Nullable OAuth2RefreshToken getRefreshToken() { | ||||
| 		return this.refreshToken; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -113,7 +113,8 @@ public class OAuth2LoginAuthenticationProvider implements AuthenticationProvider | ||||
| 			authorizationCodeAuthentication.getAuthorizationExchange(), | ||||
| 			oauth2User, | ||||
| 			mappedAuthorities, | ||||
| 			accessToken); | ||||
| 			accessToken, | ||||
| 			accessTokenResponse.getRefreshToken()); | ||||
| 		authenticationResult.setDetails(authorizationCodeAuthentication.getDetails()); | ||||
| 
 | ||||
| 		return authenticationResult; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -15,11 +15,13 @@ | ||||
|  */ | ||||
| package org.springframework.security.oauth2.client.authentication; | ||||
| 
 | ||||
| import org.springframework.lang.Nullable; | ||||
| import org.springframework.security.authentication.AbstractAuthenticationToken; | ||||
| import org.springframework.security.core.GrantedAuthority; | ||||
| import org.springframework.security.core.SpringSecurityCoreVersion; | ||||
| import org.springframework.security.oauth2.client.registration.ClientRegistration; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; | ||||
| import org.springframework.security.oauth2.core.user.OAuth2User; | ||||
| import org.springframework.util.Assert; | ||||
| @ -46,6 +48,7 @@ public class OAuth2LoginAuthenticationToken extends AbstractAuthenticationToken | ||||
| 	private ClientRegistration clientRegistration; | ||||
| 	private OAuth2AuthorizationExchange authorizationExchange; | ||||
| 	private OAuth2AccessToken accessToken; | ||||
| 	private OAuth2RefreshToken refreshToken; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This constructor should be used when the Authorization Request/Response is complete. | ||||
| @ -80,6 +83,27 @@ public class OAuth2LoginAuthenticationToken extends AbstractAuthenticationToken | ||||
| 											OAuth2User principal, | ||||
| 											Collection<? extends GrantedAuthority> authorities, | ||||
| 											OAuth2AccessToken accessToken) { | ||||
| 		this(clientRegistration, authorizationExchange, principal, authorities, accessToken, null); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This constructor should be used when the Access Token Request/Response is complete, | ||||
| 	 * which indicates that the Authorization Code Grant flow has fully completed | ||||
| 	 * and OAuth 2.0 Login has been achieved. | ||||
| 	 * | ||||
| 	 * @param clientRegistration the client registration | ||||
| 	 * @param authorizationExchange the authorization exchange | ||||
| 	 * @param principal the user {@code Principal} registered with the OAuth 2.0 Provider | ||||
| 	 * @param authorities the authorities granted to the user | ||||
| 	 * @param accessToken the access token credential | ||||
| 	 * @param refreshToken the refresh token credential | ||||
| 	 */ | ||||
| 	public OAuth2LoginAuthenticationToken(ClientRegistration clientRegistration, | ||||
| 											OAuth2AuthorizationExchange authorizationExchange, | ||||
| 											OAuth2User principal, | ||||
| 											Collection<? extends GrantedAuthority> authorities, | ||||
| 											OAuth2AccessToken accessToken, | ||||
| 											@Nullable OAuth2RefreshToken refreshToken) { | ||||
| 		super(authorities); | ||||
| 		Assert.notNull(clientRegistration, "clientRegistration cannot be null"); | ||||
| 		Assert.notNull(authorizationExchange, "authorizationExchange cannot be null"); | ||||
| @ -89,6 +113,7 @@ public class OAuth2LoginAuthenticationToken extends AbstractAuthenticationToken | ||||
| 		this.authorizationExchange = authorizationExchange; | ||||
| 		this.principal = principal; | ||||
| 		this.accessToken = accessToken; | ||||
| 		this.refreshToken = refreshToken; | ||||
| 		this.setAuthenticated(true); | ||||
| 	} | ||||
| 
 | ||||
| @ -128,4 +153,14 @@ public class OAuth2LoginAuthenticationToken extends AbstractAuthenticationToken | ||||
| 	public OAuth2AccessToken getAccessToken() { | ||||
| 		return this.accessToken; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Returns the {@link OAuth2RefreshToken refresh token}. | ||||
| 	 * | ||||
| 	 * @since 5.1 | ||||
| 	 * @return the {@link OAuth2RefreshToken} | ||||
| 	 */ | ||||
| 	public @Nullable OAuth2RefreshToken getRefreshToken() { | ||||
| 		return this.refreshToken; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -120,11 +120,13 @@ public class OAuth2LoginReactiveAuthenticationManager implements | ||||
| 							authorizationCodeAuthentication.getAuthorizationExchange(), | ||||
| 							oauth2User, | ||||
| 							mappedAuthorities, | ||||
| 							accessToken); | ||||
| 							accessToken, | ||||
| 							accessTokenResponse.getRefreshToken()); | ||||
| 					OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient( | ||||
| 							authenticationResult.getClientRegistration(), | ||||
| 							authenticationResult.getName(), | ||||
| 							authenticationResult.getAccessToken()); | ||||
| 							authenticationResult.getAccessToken(), | ||||
| 							authenticationResult.getRefreshToken()); | ||||
| 					OAuth2AuthenticationToken result =  new OAuth2AuthenticationToken( | ||||
| 							authenticationResult.getPrincipal(), | ||||
| 							authenticationResult.getAuthorities(), | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -138,12 +138,18 @@ public class NimbusAuthorizationCodeTokenResponseClient implements OAuth2AccessT | ||||
| 				accessTokenResponse.getTokens().getAccessToken().getScope().toStringList()); | ||||
| 		} | ||||
| 
 | ||||
| 		String refreshToken = null; | ||||
| 		if (accessTokenResponse.getTokens().getRefreshToken() != null) { | ||||
| 			refreshToken = accessTokenResponse.getTokens().getRefreshToken().getValue(); | ||||
| 		} | ||||
| 
 | ||||
| 		Map<String, Object> additionalParameters = new LinkedHashMap<>(accessTokenResponse.getCustomParameters()); | ||||
| 
 | ||||
| 		return OAuth2AccessTokenResponse.withToken(accessToken) | ||||
| 			.tokenType(accessTokenType) | ||||
| 			.expiresIn(expiresIn) | ||||
| 			.scopes(scopes) | ||||
| 			.refreshToken(refreshToken) | ||||
| 			.additionalParameters(additionalParameters) | ||||
| 			.build(); | ||||
| 	} | ||||
|  | ||||
| @ -118,6 +118,11 @@ public class NimbusReactiveAuthorizationCodeTokenResponseClient implements React | ||||
| 									accessToken.getScope().toStringList()); | ||||
| 						} | ||||
| 
 | ||||
| 						String refreshToken = null; | ||||
| 						if (accessTokenResponse.getTokens().getRefreshToken() != null) { | ||||
| 							refreshToken = accessTokenResponse.getTokens().getRefreshToken().getValue(); | ||||
| 						} | ||||
| 
 | ||||
| 						Map<String, Object> additionalParameters = new LinkedHashMap<>( | ||||
| 								accessTokenResponse.getCustomParameters()); | ||||
| 
 | ||||
| @ -125,6 +130,7 @@ public class NimbusReactiveAuthorizationCodeTokenResponseClient implements React | ||||
| 								.tokenType(accessTokenType) | ||||
| 								.expiresIn(expiresIn) | ||||
| 								.scopes(scopes) | ||||
| 								.refreshToken(refreshToken) | ||||
| 								.additionalParameters(additionalParameters) | ||||
| 								.build(); | ||||
| 					}); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -27,7 +27,6 @@ import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; | ||||
| import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; | ||||
| import org.springframework.security.oauth2.client.registration.ClientRegistration; | ||||
| import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||||
| import org.springframework.security.oauth2.core.OAuth2Error; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; | ||||
| @ -142,8 +141,6 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati | ||||
| 					authorizationCodeAuthentication.getClientRegistration(), | ||||
| 					authorizationCodeAuthentication.getAuthorizationExchange())); | ||||
| 
 | ||||
| 		OAuth2AccessToken accessToken = accessTokenResponse.getAccessToken(); | ||||
| 
 | ||||
| 		ClientRegistration clientRegistration = authorizationCodeAuthentication.getClientRegistration(); | ||||
| 
 | ||||
| 		if (!accessTokenResponse.getAdditionalParameters().containsKey(OidcParameterNames.ID_TOKEN)) { | ||||
| @ -161,7 +158,7 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati | ||||
| 		this.validateIdToken(idToken, clientRegistration); | ||||
| 
 | ||||
| 		OidcUser oidcUser = this.userService.loadUser( | ||||
| 			new OidcUserRequest(clientRegistration, accessToken, idToken)); | ||||
| 			new OidcUserRequest(clientRegistration, accessTokenResponse.getAccessToken(), idToken)); | ||||
| 
 | ||||
| 		Collection<? extends GrantedAuthority> mappedAuthorities = | ||||
| 			this.authoritiesMapper.mapAuthorities(oidcUser.getAuthorities()); | ||||
| @ -171,7 +168,8 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati | ||||
| 			authorizationCodeAuthentication.getAuthorizationExchange(), | ||||
| 			oidcUser, | ||||
| 			mappedAuthorities, | ||||
| 			accessToken); | ||||
| 			accessTokenResponse.getAccessToken(), | ||||
| 			accessTokenResponse.getRefreshToken()); | ||||
| 		authenticationResult.setDetails(authorizationCodeAuthentication.getDetails()); | ||||
| 
 | ||||
| 		return authenticationResult; | ||||
|  | ||||
| @ -198,7 +198,8 @@ public class OAuth2AuthorizationCodeGrantFilter extends OncePerRequestFilter { | ||||
| 		OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient( | ||||
| 			authenticationResult.getClientRegistration(), | ||||
| 			currentAuthentication.getName(), | ||||
| 			authenticationResult.getAccessToken()); | ||||
| 			authenticationResult.getAccessToken(), | ||||
| 			authenticationResult.getRefreshToken()); | ||||
| 
 | ||||
| 		this.authorizedClientService.saveAuthorizedClient(authorizedClient, currentAuthentication); | ||||
| 
 | ||||
|  | ||||
| @ -173,7 +173,8 @@ public class OAuth2LoginAuthenticationFilter extends AbstractAuthenticationProce | ||||
| 		OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient( | ||||
| 			authenticationResult.getClientRegistration(), | ||||
| 			oauth2Authentication.getName(), | ||||
| 			authenticationResult.getAccessToken()); | ||||
| 			authenticationResult.getAccessToken(), | ||||
| 			authenticationResult.getRefreshToken()); | ||||
| 
 | ||||
| 		this.authorizedClientService.saveAuthorizedClient(authorizedClient, oauth2Authentication); | ||||
| 
 | ||||
|  | ||||
| @ -27,6 +27,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||||
| import org.springframework.security.oauth2.core.OAuth2Error; | ||||
| import org.springframework.security.oauth2.core.OAuth2ErrorCodes; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; | ||||
| @ -122,8 +123,10 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests { | ||||
| 	@Test | ||||
| 	public void authenticateWhenAuthorizationSuccessResponseThenExchangedForAccessToken() { | ||||
| 		OAuth2AccessToken accessToken = mock(OAuth2AccessToken.class); | ||||
| 		OAuth2RefreshToken refreshToken = mock(OAuth2RefreshToken.class); | ||||
| 		OAuth2AccessTokenResponse accessTokenResponse = mock(OAuth2AccessTokenResponse.class); | ||||
| 		when(accessTokenResponse.getAccessToken()).thenReturn(accessToken); | ||||
| 		when(accessTokenResponse.getRefreshToken()).thenReturn(refreshToken); | ||||
| 		when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse); | ||||
| 
 | ||||
| 		OAuth2AuthorizationCodeAuthenticationToken authenticationResult = | ||||
| @ -137,5 +140,6 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests { | ||||
| 		assertThat(authenticationResult.getClientRegistration()).isEqualTo(this.clientRegistration); | ||||
| 		assertThat(authenticationResult.getAuthorizationExchange()).isEqualTo(this.authorizationExchange); | ||||
| 		assertThat(authenticationResult.getAccessToken()).isEqualTo(accessToken); | ||||
| 		assertThat(authenticationResult.getRefreshToken()).isEqualTo(refreshToken); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -35,6 +35,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||||
| import org.springframework.security.oauth2.core.OAuth2Error; | ||||
| import org.springframework.security.oauth2.core.OAuth2ErrorCodes; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; | ||||
| @ -164,8 +165,10 @@ public class OAuth2LoginAuthenticationProviderTests { | ||||
| 	@Test | ||||
| 	public void authenticateWhenLoginSuccessThenReturnAuthentication() { | ||||
| 		OAuth2AccessToken accessToken = mock(OAuth2AccessToken.class); | ||||
| 		OAuth2RefreshToken refreshToken = mock(OAuth2RefreshToken.class); | ||||
| 		OAuth2AccessTokenResponse accessTokenResponse = mock(OAuth2AccessTokenResponse.class); | ||||
| 		when(accessTokenResponse.getAccessToken()).thenReturn(accessToken); | ||||
| 		when(accessTokenResponse.getRefreshToken()).thenReturn(refreshToken); | ||||
| 		when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse); | ||||
| 
 | ||||
| 		OAuth2User principal = mock(OAuth2User.class); | ||||
| @ -185,6 +188,7 @@ public class OAuth2LoginAuthenticationProviderTests { | ||||
| 		assertThat(authentication.getClientRegistration()).isEqualTo(this.clientRegistration); | ||||
| 		assertThat(authentication.getAuthorizationExchange()).isEqualTo(this.authorizationExchange); | ||||
| 		assertThat(authentication.getAccessToken()).isEqualTo(accessToken); | ||||
| 		assertThat(authentication.getRefreshToken()).isEqualTo(refreshToken); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -91,6 +91,7 @@ public class NimbusAuthorizationCodeTokenResponseClientTests { | ||||
| 			"   \"token_type\": \"bearer\",\n" + | ||||
| 			"   \"expires_in\": \"3600\",\n" + | ||||
| 			"   \"scope\": \"openid profile\",\n" + | ||||
| 			"	\"refresh_token\": \"refresh-token-1234\",\n" + | ||||
| 			"   \"custom_parameter_1\": \"custom-value-1\",\n" + | ||||
| 			"   \"custom_parameter_2\": \"custom-value-2\"\n" + | ||||
| 			"}\n"; | ||||
| @ -115,6 +116,7 @@ public class NimbusAuthorizationCodeTokenResponseClientTests { | ||||
| 		assertThat(accessTokenResponse.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER); | ||||
| 		assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isBetween(expiresAtBefore, expiresAtAfter); | ||||
| 		assertThat(accessTokenResponse.getAccessToken().getScopes()).containsExactly("openid", "profile"); | ||||
| 		assertThat(accessTokenResponse.getRefreshToken().getTokenValue()).isEqualTo("refresh-token-1234"); | ||||
| 		assertThat(accessTokenResponse.getAdditionalParameters().size()).isEqualTo(2); | ||||
| 		assertThat(accessTokenResponse.getAdditionalParameters()).containsEntry("custom_parameter_1", "custom-value-1"); | ||||
| 		assertThat(accessTokenResponse.getAdditionalParameters()).containsEntry("custom_parameter_2", "custom-value-2"); | ||||
|  | ||||
| @ -85,6 +85,7 @@ public class NimbusReactiveAuthorizationCodeTokenResponseClientTests { | ||||
| 				"   \"token_type\": \"bearer\",\n" + | ||||
| 				"   \"expires_in\": \"3600\",\n" + | ||||
| 				"   \"scope\": \"openid profile\",\n" + | ||||
| 				"	\"refresh_token\": \"refresh-token-1234\",\n" + | ||||
| 				"   \"custom_parameter_1\": \"custom-value-1\",\n" + | ||||
| 				"   \"custom_parameter_2\": \"custom-value-2\"\n" + | ||||
| 				"}\n"; | ||||
| @ -102,6 +103,7 @@ public class NimbusReactiveAuthorizationCodeTokenResponseClientTests { | ||||
| 				OAuth2AccessToken.TokenType.BEARER); | ||||
| 		assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isBetween(expiresAtBefore, expiresAtAfter); | ||||
| 		assertThat(accessTokenResponse.getAccessToken().getScopes()).containsExactly("openid", "profile"); | ||||
| 		assertThat(accessTokenResponse.getRefreshToken().getTokenValue()).isEqualTo("refresh-token-1234"); | ||||
| 		assertThat(accessTokenResponse.getAdditionalParameters().size()).isEqualTo(2); | ||||
| 		assertThat(accessTokenResponse.getAdditionalParameters()).containsEntry("custom_parameter_1", "custom-value-1"); | ||||
| 		assertThat(accessTokenResponse.getAdditionalParameters()).containsEntry("custom_parameter_2", "custom-value-2"); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -37,6 +37,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||||
| import org.springframework.security.oauth2.core.OAuth2Error; | ||||
| import org.springframework.security.oauth2.core.OAuth2ErrorCodes; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; | ||||
| @ -78,6 +79,7 @@ public class OidcAuthorizationCodeAuthenticationProviderTests { | ||||
| 	private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient; | ||||
| 	private OAuth2AccessTokenResponse accessTokenResponse; | ||||
| 	private OAuth2AccessToken accessToken; | ||||
| 	private OAuth2RefreshToken refreshToken; | ||||
| 	private OAuth2UserService<OidcUserRequest, OidcUser> userService; | ||||
| 	private OidcAuthorizationCodeAuthenticationProvider authenticationProvider; | ||||
| 
 | ||||
| @ -95,6 +97,7 @@ public class OidcAuthorizationCodeAuthenticationProviderTests { | ||||
| 		this.accessTokenResponseClient = mock(OAuth2AccessTokenResponseClient.class); | ||||
| 		this.accessTokenResponse = mock(OAuth2AccessTokenResponse.class); | ||||
| 		this.accessToken = mock(OAuth2AccessToken.class); | ||||
| 		this.refreshToken = mock(OAuth2RefreshToken.class); | ||||
| 		this.userService = mock(OAuth2UserService.class); | ||||
| 		this.authenticationProvider = PowerMockito.spy( | ||||
| 			new OidcAuthorizationCodeAuthenticationProvider(this.accessTokenResponseClient, this.userService)); | ||||
| @ -109,6 +112,7 @@ public class OidcAuthorizationCodeAuthenticationProviderTests { | ||||
| 		when(this.authorizationRequest.getRedirectUri()).thenReturn("http://example.com"); | ||||
| 		when(this.authorizationResponse.getRedirectUri()).thenReturn("http://example.com"); | ||||
| 		when(this.accessTokenResponse.getAccessToken()).thenReturn(this.accessToken); | ||||
| 		when(this.accessTokenResponse.getRefreshToken()).thenReturn(this.refreshToken); | ||||
| 		Map<String, Object> additionalParameters = new HashMap<>(); | ||||
| 		additionalParameters.put(OidcParameterNames.ID_TOKEN, "id-token"); | ||||
| 		when(this.accessTokenResponse.getAdditionalParameters()).thenReturn(additionalParameters); | ||||
| @ -365,6 +369,7 @@ public class OidcAuthorizationCodeAuthenticationProviderTests { | ||||
| 		assertThat(authentication.getClientRegistration()).isEqualTo(this.clientRegistration); | ||||
| 		assertThat(authentication.getAuthorizationExchange()).isEqualTo(this.authorizationExchange); | ||||
| 		assertThat(authentication.getAccessToken()).isEqualTo(this.accessToken); | ||||
| 		assertThat(authentication.getRefreshToken()).isEqualTo(this.refreshToken); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
|  | ||||
| @ -41,6 +41,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||||
| import org.springframework.security.oauth2.core.OAuth2Error; | ||||
| import org.springframework.security.oauth2.core.OAuth2ErrorCodes; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; | ||||
| @ -238,6 +239,7 @@ public class OAuth2AuthorizationCodeGrantFilterTests { | ||||
| 		assertThat(authorizedClient.getClientRegistration()).isEqualTo(this.registration1); | ||||
| 		assertThat(authorizedClient.getPrincipalName()).isEqualTo(this.principalName1); | ||||
| 		assertThat(authorizedClient.getAccessToken()).isNotNull(); | ||||
| 		assertThat(authorizedClient.getRefreshToken()).isNotNull(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| @ -299,6 +301,7 @@ public class OAuth2AuthorizationCodeGrantFilterTests { | ||||
| 		when(authentication.getClientRegistration()).thenReturn(registration); | ||||
| 		when(authentication.getAuthorizationExchange()).thenReturn(mock(OAuth2AuthorizationExchange.class)); | ||||
| 		when(authentication.getAccessToken()).thenReturn(mock(OAuth2AccessToken.class)); | ||||
| 		when(authentication.getRefreshToken()).thenReturn(mock(OAuth2RefreshToken.class)); | ||||
| 		when(this.authenticationManager.authenticate(any(Authentication.class))).thenReturn(authentication); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -40,6 +40,7 @@ import org.springframework.security.oauth2.core.ClientAuthenticationMethod; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||||
| import org.springframework.security.oauth2.core.OAuth2ErrorCodes; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; | ||||
| @ -281,6 +282,7 @@ public class OAuth2LoginAuthenticationFilterTests { | ||||
| 		assertThat(authorizedClient.getClientRegistration()).isEqualTo(this.registration1); | ||||
| 		assertThat(authorizedClient.getPrincipalName()).isEqualTo(this.principalName1); | ||||
| 		assertThat(authorizedClient.getAccessToken()).isNotNull(); | ||||
| 		assertThat(authorizedClient.getRefreshToken()).isNotNull(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| @ -328,6 +330,7 @@ public class OAuth2LoginAuthenticationFilterTests { | ||||
| 		when(loginAuthentication.getClientRegistration()).thenReturn(registration); | ||||
| 		when(loginAuthentication.getAuthorizationExchange()).thenReturn(mock(OAuth2AuthorizationExchange.class)); | ||||
| 		when(loginAuthentication.getAccessToken()).thenReturn(mock(OAuth2AccessToken.class)); | ||||
| 		when(loginAuthentication.getRefreshToken()).thenReturn(mock(OAuth2RefreshToken.class)); | ||||
| 		when(this.authenticationManager.authenticate(any(Authentication.class))).thenReturn(loginAuthentication); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -37,6 +37,7 @@ public final class AuthorizationGrantType implements Serializable { | ||||
| 	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; | ||||
| 	public static final AuthorizationGrantType AUTHORIZATION_CODE = new AuthorizationGrantType("authorization_code"); | ||||
| 	public static final AuthorizationGrantType IMPLICIT = new AuthorizationGrantType("implicit"); | ||||
| 	public static final AuthorizationGrantType REFRESH_TOKEN = new AuthorizationGrantType("refresh_token"); | ||||
| 	private final String value; | ||||
| 
 | ||||
| 	/** | ||||
|  | ||||
| @ -0,0 +1,46 @@ | ||||
| /* | ||||
|  * Copyright 2002-2018 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 | ||||
|  * | ||||
|  *      http://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.core; | ||||
| 
 | ||||
| import java.time.Instant; | ||||
| 
 | ||||
| /** | ||||
|  * An implementation of an {@link AbstractOAuth2Token} representing an OAuth 2.0 Refresh Token. | ||||
|  * | ||||
|  * <p> | ||||
|  * A refresh token is a credential that represents an authorization | ||||
|  * granted by the resource owner to the client. | ||||
|  * It is used by the client to obtain a new access token when the current access token | ||||
|  * becomes invalid or expires, or to obtain additional access tokens with identical or narrower scope. | ||||
|  * | ||||
|  * @author Joe Grandja | ||||
|  * @since 5.1 | ||||
|  * @see OAuth2AccessToken | ||||
|  * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-1.5">Section 1.5 Refresh Token</a> | ||||
|  */ | ||||
| public class OAuth2RefreshToken extends AbstractOAuth2Token { | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Constructs an {@code OAuth2RefreshToken} using the provided parameters. | ||||
| 	 * | ||||
| 	 * @param tokenValue the token value | ||||
| 	 * @param issuedAt the time at which the token was issued | ||||
| 	 * @param expiresAt the expiration time on or after which the token MUST NOT be accepted | ||||
| 	 */ | ||||
| 	public OAuth2RefreshToken(String tokenValue, Instant issuedAt, Instant expiresAt) { | ||||
| 		super(tokenValue, issuedAt, expiresAt); | ||||
| 	} | ||||
| } | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -15,8 +15,11 @@ | ||||
|  */ | ||||
| package org.springframework.security.oauth2.core.endpoint; | ||||
| 
 | ||||
| import org.springframework.lang.Nullable; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2RefreshToken; | ||||
| import org.springframework.util.CollectionUtils; | ||||
| import org.springframework.util.StringUtils; | ||||
| 
 | ||||
| import java.time.Instant; | ||||
| import java.util.Collections; | ||||
| @ -29,10 +32,12 @@ import java.util.Set; | ||||
|  * @author Joe Grandja | ||||
|  * @since 5.0 | ||||
|  * @see OAuth2AccessToken | ||||
|  * @see OAuth2RefreshToken | ||||
|  * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-5.1">Section 5.1 Access Token Response</a> | ||||
|  */ | ||||
| public final class OAuth2AccessTokenResponse { | ||||
| 	private OAuth2AccessToken accessToken; | ||||
| 	private OAuth2RefreshToken refreshToken; | ||||
| 	private Map<String, Object> additionalParameters; | ||||
| 
 | ||||
| 	private OAuth2AccessTokenResponse() { | ||||
| @ -47,6 +52,16 @@ public final class OAuth2AccessTokenResponse { | ||||
| 		return this.accessToken; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Returns the {@link OAuth2RefreshToken Refresh Token}. | ||||
| 	 * | ||||
| 	 * @since 5.1 | ||||
| 	 * @return the {@link OAuth2RefreshToken} | ||||
| 	 */ | ||||
| 	public @Nullable OAuth2RefreshToken getRefreshToken() { | ||||
| 		return this.refreshToken; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Returns the additional parameters returned in the response. | ||||
| 	 * | ||||
| @ -74,6 +89,7 @@ public final class OAuth2AccessTokenResponse { | ||||
| 		private OAuth2AccessToken.TokenType tokenType; | ||||
| 		private long expiresIn; | ||||
| 		private Set<String> scopes; | ||||
| 		private String refreshToken; | ||||
| 		private Map<String, Object> additionalParameters; | ||||
| 
 | ||||
| 		private Builder(String tokenValue) { | ||||
| @ -113,6 +129,17 @@ public final class OAuth2AccessTokenResponse { | ||||
| 			return this; | ||||
| 		} | ||||
| 
 | ||||
| 		/** | ||||
| 		 * Sets the refresh token associated to the access token. | ||||
| 		 * | ||||
| 		 * @param refreshToken the refresh token associated to the access token. | ||||
| 		 * @return the {@link Builder} | ||||
| 		 */ | ||||
| 		public Builder refreshToken(String refreshToken) { | ||||
| 			this.refreshToken = refreshToken; | ||||
| 			return this; | ||||
| 		} | ||||
| 
 | ||||
| 		/** | ||||
| 		 * Sets the additional parameters returned in the response. | ||||
| 		 * | ||||
| @ -142,6 +169,14 @@ public final class OAuth2AccessTokenResponse { | ||||
| 			OAuth2AccessTokenResponse accessTokenResponse = new OAuth2AccessTokenResponse(); | ||||
| 			accessTokenResponse.accessToken = new OAuth2AccessToken( | ||||
| 				this.tokenType, this.tokenValue, issuedAt, expiresAt, this.scopes); | ||||
| 			if (StringUtils.hasText(this.refreshToken)) { | ||||
| 				// The Access Token response does not return an expires_in for the Refresh Token, | ||||
| 				// therefore, we'll default to +1 second from issuedAt time. | ||||
| 				// NOTE: | ||||
| 				// The expiry or invalidity of a Refresh Token can only be determined by performing | ||||
| 				// the refresh_token grant and if it fails than likely it has expired or has been invalidated. | ||||
| 				accessTokenResponse.refreshToken = new OAuth2RefreshToken(this.refreshToken, issuedAt, issuedAt.plusSeconds(1)); | ||||
| 			} | ||||
| 			accessTokenResponse.additionalParameters = Collections.unmodifiableMap( | ||||
| 				CollectionUtils.isEmpty(this.additionalParameters) ? Collections.emptyMap() : this.additionalParameters); | ||||
| 			return accessTokenResponse; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -40,4 +40,9 @@ public class AuthorizationGrantTypeTests { | ||||
| 	public void getValueWhenImplicitGrantTypeThenReturnImplicit() { | ||||
| 		assertThat(AuthorizationGrantType.IMPLICIT.getValue()).isEqualTo("implicit"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void getValueWhenRefreshTokenGrantTypeThenReturnRefreshToken() { | ||||
| 		assertThat(AuthorizationGrantType.REFRESH_TOKEN.getValue()).isEqualTo("refresh_token"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2018 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. | ||||
| @ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; | ||||
|  */ | ||||
| public class OAuth2AccessTokenResponseTests { | ||||
| 	private static final String TOKEN_VALUE = "access-token"; | ||||
| 	private static final String REFRESH_TOKEN_VALUE = "refresh-token"; | ||||
| 	private static final long EXPIRES_IN = Instant.now().plusSeconds(5).toEpochMilli(); | ||||
| 
 | ||||
| 	@Test(expected = IllegalArgumentException.class) | ||||
| @ -88,6 +89,7 @@ public class OAuth2AccessTokenResponseTests { | ||||
| 			.tokenType(OAuth2AccessToken.TokenType.BEARER) | ||||
| 			.expiresIn(expiresAt.toEpochMilli()) | ||||
| 			.scopes(scopes) | ||||
| 			.refreshToken(REFRESH_TOKEN_VALUE) | ||||
| 			.additionalParameters(additionalParameters) | ||||
| 			.build(); | ||||
| 
 | ||||
| @ -97,6 +99,7 @@ public class OAuth2AccessTokenResponseTests { | ||||
| 		assertThat(tokenResponse.getAccessToken().getIssuedAt()).isNotNull(); | ||||
| 		assertThat(tokenResponse.getAccessToken().getExpiresAt()).isAfterOrEqualTo(expiresAt); | ||||
| 		assertThat(tokenResponse.getAccessToken().getScopes()).isEqualTo(scopes); | ||||
| 		assertThat(tokenResponse.getRefreshToken().getTokenValue()).isEqualTo(REFRESH_TOKEN_VALUE); | ||||
| 		assertThat(tokenResponse.getAdditionalParameters()).isEqualTo(additionalParameters); | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user