Polish gh-4557

This commit is contained in:
Joe Grandja
2020-02-11 04:20:59 -05:00
parent 71a5c9521c
commit ff8002eb2e
27 changed files with 618 additions and 932 deletions

View File

@@ -18,16 +18,14 @@ package org.springframework.security.config.http;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.internal.util.MockUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
@@ -38,17 +36,15 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.client.web.AuthenticatedPrincipalOAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationRequests;
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.oauth2.core.user.TestOAuth2Users;
import org.springframework.security.oauth2.jwt.Jwt;
@@ -56,7 +52,7 @@ import org.springframework.security.oauth2.jwt.JwtDecoderFactory;
import org.springframework.security.oauth2.jwt.TestJwts;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
@@ -68,19 +64,15 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses.accessTokenResponse;
import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses.oidcAccessTokenResponse;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Tests for {@link OAuth2LoginBeanDefinitionParser}.
*
@@ -95,17 +87,11 @@ public class OAuth2LoginBeanDefinitionParserTests {
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
@Autowired
private OAuth2LoginAuthenticationFilter oauth2LoginAuthenticationFilter;
@Autowired(required = false)
private OAuth2AuthorizedClientRepository authorizedClientRepository;
@Autowired(required = false)
private OAuth2AuthorizedClientRepository oauth2AuthorizedClientRepository;
@Autowired(required = false)
private OAuth2AuthorizedClientService oauth2AuthorizedClientService;
@Autowired
SecurityContextRepository securityContextRepository;
private OAuth2AuthorizedClientService authorizedClientService;
@Autowired(required = false)
private ApplicationListener<AuthenticationSuccessEvent> authenticationSuccessListener;
@@ -113,6 +99,9 @@ public class OAuth2LoginBeanDefinitionParserTests {
@Autowired(required = false)
private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository;
@Autowired(required = false)
private OAuth2AuthorizationRequestResolver authorizationRequestResolver;
@Autowired(required = false)
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient;
@@ -123,10 +112,7 @@ public class OAuth2LoginBeanDefinitionParserTests {
private JwtDecoderFactory<ClientRegistration> jwtDecoderFactory;
@Autowired(required = false)
private OAuth2AuthorizationRequestResolver oauth2AuthorizationRequestResolver;
@Autowired(required = false)
private GrantedAuthoritiesMapper grantedAuthoritiesMapper;
private GrantedAuthoritiesMapper userAuthoritiesMapper;
@Autowired(required = false)
private AuthenticationFailureHandler authenticationFailureHandler;
@@ -134,14 +120,19 @@ public class OAuth2LoginBeanDefinitionParserTests {
@Autowired(required = false)
private AuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired(required = false)
private RequestCache requestCache;
@Autowired
private MockMvc mvc;
@Test
public void requestLoginWhenMultiClientRegistrationThenReturnLoginPageWithOauth2Login() throws Exception {
public void requestLoginWhenMultiClientRegistrationThenReturnLoginPageWithClients() throws Exception {
this.spring.configLocations(this.xml("MultiClientRegistration")).autowire();
MvcResult result = this.mvc.perform(get("/login")).andExpect(status().is2xxSuccessful()).andReturn();
MvcResult result = this.mvc.perform(get("/login"))
.andExpect(status().is2xxSuccessful())
.andReturn();
assertThat(result.getResponse().getContentAsString())
.contains("<a href=\"/oauth2/authorization/google-login\">Google</a>");
@@ -152,10 +143,13 @@ public class OAuth2LoginBeanDefinitionParserTests {
// gh-5347
@Test
public void requestWhenSingleClientRegistrationThenAutoRedirect() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithinSameFile")).autowire();
this.spring.configLocations(this.xml("SingleClientRegistration")).autowire();
this.mvc.perform(get("/")).andExpect(status().is3xxRedirection())
this.mvc.perform(get("/"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/oauth2/authorization/google-login"));
verify(requestCache).saveRequest(any(), any());
}
// gh-5347
@@ -164,7 +158,8 @@ public class OAuth2LoginBeanDefinitionParserTests {
throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration")).autowire();
this.mvc.perform(get("/favicon.ico").accept(new MediaType("image", "*"))).andExpect(status().is3xxRedirection())
this.mvc.perform(get("/favicon.ico").accept(new MediaType("image", "*")))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/login"));
}
@@ -174,7 +169,8 @@ public class OAuth2LoginBeanDefinitionParserTests {
throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration")).autowire();
this.mvc.perform(get("/").header("X-Requested-With", "XMLHttpRequest")).andExpect(status().is3xxRedirection())
this.mvc.perform(get("/").header("X-Requested-With", "XMLHttpRequest"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/login"));
}
@@ -188,66 +184,65 @@ public class OAuth2LoginBeanDefinitionParserTests {
params.add("state", "state123");
this.mvc.perform(get("/login/oauth2/code/google").params(params));
// assertions
ArgumentCaptor<AuthenticationException> exceptionCaptor = ArgumentCaptor
.forClass(AuthenticationException.class);
verify(authenticationFailureHandler).onAuthenticationFailure(any(), any(), exceptionCaptor.capture());
AuthenticationException excValue = exceptionCaptor.getValue();
assertThat(excValue).isInstanceOf(OAuth2AuthenticationException.class);
assertThat(((OAuth2AuthenticationException) excValue).getError().getErrorCode())
AuthenticationException exception = exceptionCaptor.getValue();
assertThat(exception).isInstanceOf(OAuth2AuthenticationException.class);
assertThat(((OAuth2AuthenticationException) exception).getError().getErrorCode())
.isEqualTo("authorization_request_not_found");
}
@Test
public void requestWhenAuthorizationResponseValidThenAuthenticate() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithTestConfiguration")).autowire();
this.spring.configLocations(this.xml("MultiClientRegistration-WithCustomConfiguration")).autowire();
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "github-login");
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/google").params(params)).andExpect(status().is2xxSuccessful());
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/code/github-login").params(params))
.andExpect(status().is2xxSuccessful());
ArgumentCaptor<Authentication> authenticationCaptor = ArgumentCaptor.forClass(Authentication.class);
verify(authenticationSuccessHandler).onAuthenticationSuccess(any(), any(), authenticationCaptor.capture());
Authentication authenticationValue = authenticationCaptor.getValue();
assertThat(authenticationValue.getAuthorities()).hasSize(1);
assertThat(authenticationValue.getAuthorities()).first().isInstanceOf(SimpleGrantedAuthority.class)
.hasToString("ROLE_USER");
Authentication authentication = authenticationCaptor.getValue();
assertThat(authentication.getPrincipal()).isInstanceOf(OAuth2User.class);
}
// gh-6009
@Test
public void requestWhenAuthorizationResponseValidThenAuthenticationSuccessEventPublished() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithTestConfiguration")).autowire();
this.spring.configLocations(this.xml("MultiClientRegistration-WithCustomConfiguration")).autowire();
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "github-login");
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/google").params(params));
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/code/github-login").params(params));
// assertions
verify(authenticationSuccessListener).onApplicationEvent(any(AuthenticationSuccessEvent.class));
}
@@ -255,149 +250,120 @@ public class OAuth2LoginBeanDefinitionParserTests {
public void requestWhenOidcAuthenticationResponseValidThenJwtDecoderFactoryCalled() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithJwtDecoderFactoryAndDefaultSuccessHandler"))
.autowire();
Map<String, Object> additionalParameters = new HashMap<>();
additionalParameters.put(OidcParameterNames.ID_TOKEN, "token123");
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().additionalParameters(additionalParameters)
.build();
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.oidcRequest()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
OAuth2AccessTokenResponse accessTokenResponse = oidcAccessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
Jwt jwt = TestJwts.user();
when(this.jwtDecoderFactory.createDecoder(any())).thenReturn(token -> jwt);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.scope("openid").build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/google").params(params)).andExpect(status().is3xxRedirection())
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/code/google-login").params(params))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/"));
verify(this.jwtDecoderFactory).createDecoder(any());
verify(this.requestCache).getRequest(any(), any());
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void requestWhenCustomGrantedAuthoritiesMapperThenCalled() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithCustomGrantedAuthorities")).autowire();
Map<String, Object> additionalParameters = new HashMap<>();
additionalParameters.put(OidcParameterNames.ID_TOKEN, "token123");
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().additionalParameters(additionalParameters)
.build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_OAUTH2_USER");
when(this.grantedAuthoritiesMapper.mapAuthorities(any()))
.thenReturn((Collection) Collections.singletonList(grantedAuthority));
this.spring.configLocations(this.xml("MultiClientRegistration-WithCustomGrantedAuthorities")).autowire();
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "github-login");
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/google").params(params)).andExpect(status().is2xxSuccessful());
ArgumentCaptor<Authentication> authenticationCaptor = ArgumentCaptor.forClass(Authentication.class);
verify(authenticationSuccessHandler).onAuthenticationSuccess(any(), any(), authenticationCaptor.capture());
Authentication authenticationValue = authenticationCaptor.getValue();
assertThat(authenticationValue.getAuthorities()).hasSize(1);
assertThat(authenticationValue.getAuthorities()).first().isInstanceOf(SimpleGrantedAuthority.class)
.hasToString("ROLE_OAUTH2_USER");
// re-setup for OIDC test
Jwt jwt = TestJwts.user();
when(this.jwtDecoderFactory.createDecoder(any())).thenReturn(token -> jwt);
grantedAuthority = new SimpleGrantedAuthority("ROLE_OIDC_USER");
when(this.grantedAuthoritiesMapper.mapAuthorities(any()))
.thenReturn((Collection) Collections.singletonList(grantedAuthority));
authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes).scope("openid").build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
this.mvc.perform(get("/login/oauth2/code/google").params(params)).andExpect(status().is2xxSuccessful());
authenticationCaptor = ArgumentCaptor.forClass(Authentication.class);
verify(authenticationSuccessHandler, times(2)).onAuthenticationSuccess(any(), any(),
authenticationCaptor.capture());
authenticationValue = authenticationCaptor.getValue();
assertThat(authenticationValue.getAuthorities()).hasSize(1);
assertThat(authenticationValue.getAuthorities()).first().isInstanceOf(SimpleGrantedAuthority.class)
.hasToString("ROLE_OIDC_USER");
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void successOidcLoginWhenSingleClientRegistrationAndCustomAuthoritiesThenReturnSuccessWithCorrectAuthorities()
throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithJwtDecoderFactory")).autowire();
Map<String, Object> additionalParameters = new HashMap<>();
additionalParameters.put(OidcParameterNames.ID_TOKEN, "token123");
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().additionalParameters(additionalParameters)
.build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
Jwt jwt = TestJwts.user();
when(this.jwtDecoderFactory.createDecoder(any())).thenReturn(token -> jwt);
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_OIDC_USER");
when(this.grantedAuthoritiesMapper.mapAuthorities(any()))
.thenReturn((Collection) Collections.singletonList(grantedAuthority));
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.scope("openid").build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/google").params(params)).andExpect(status().is2xxSuccessful());
ArgumentCaptor<Authentication> authenticationCaptor = ArgumentCaptor.forClass(Authentication.class);
verify(authenticationSuccessHandler).onAuthenticationSuccess(any(), any(), authenticationCaptor.capture());
Authentication authenticationValue = authenticationCaptor.getValue();
assertThat(authenticationValue.getAuthorities()).hasSize(1);
assertThat(authenticationValue.getAuthorities()).first().isInstanceOf(SimpleGrantedAuthority.class)
.hasToString("ROLE_OIDC_USER");
}
// gh-5488
@Test
public void requestWhenCustomLoginProcessingUrlThenProcessAuthentication() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithCustomLoginProcessingUrl")).autowire();
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
when(this.userAuthoritiesMapper.mapAuthorities(any())).thenReturn(
(Collection) AuthorityUtils.createAuthorityList("ROLE_OAUTH2_USER"));
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/google").params(params)).andExpect(status().is2xxSuccessful());
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/code/github-login").params(params))
.andExpect(status().is2xxSuccessful());
ArgumentCaptor<Authentication> authenticationCaptor = ArgumentCaptor.forClass(Authentication.class);
verify(authenticationSuccessHandler).onAuthenticationSuccess(any(), any(), authenticationCaptor.capture());
Authentication authenticationValue = authenticationCaptor.getValue();
assertThat(authenticationValue.getAuthorities()).hasSize(1);
assertThat(authenticationValue.getAuthorities()).first().isInstanceOf(SimpleGrantedAuthority.class)
.hasToString("ROLE_USER");
Authentication authentication = authenticationCaptor.getValue();
assertThat(authentication.getPrincipal()).isInstanceOf(OAuth2User.class);
assertThat(authentication.getAuthorities()).hasSize(1);
assertThat(authentication.getAuthorities()).first().isInstanceOf(SimpleGrantedAuthority.class)
.hasToString("ROLE_OAUTH2_USER");
// re-setup for OIDC test
attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
authorizationRequest = TestOAuth2AuthorizationRequests.oidcRequest()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
accessTokenResponse = oidcAccessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
Jwt jwt = TestJwts.user();
when(this.jwtDecoderFactory.createDecoder(any())).thenReturn(token -> jwt);
when(this.userAuthoritiesMapper.mapAuthorities(any()))
.thenReturn((Collection) AuthorityUtils.createAuthorityList("ROLE_OIDC_USER"));
this.mvc.perform(get("/login/oauth2/code/google-login").params(params))
.andExpect(status().is2xxSuccessful());
authenticationCaptor = ArgumentCaptor.forClass(Authentication.class);
verify(authenticationSuccessHandler, times(2)).onAuthenticationSuccess(any(), any(),
authenticationCaptor.capture());
authentication = authenticationCaptor.getValue();
assertThat(authentication.getPrincipal()).isInstanceOf(OidcUser.class);
assertThat(authentication.getAuthorities()).hasSize(1);
assertThat(authentication.getAuthorities()).first().isInstanceOf(SimpleGrantedAuthority.class)
.hasToString("ROLE_OIDC_USER");
}
// gh-5488
@Test
public void requestWhenCustomLoginProcessingUrlThenProcessAuthentication() throws Exception {
this.spring.configLocations(this.xml("MultiClientRegistration-WithCustomLoginProcessingUrl")).autowire();
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "github-login");
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/github-login").params(params))
.andExpect(status().is2xxSuccessful());
ArgumentCaptor<Authentication> authenticationCaptor = ArgumentCaptor.forClass(Authentication.class);
verify(authenticationSuccessHandler).onAuthenticationSuccess(any(), any(), authenticationCaptor.capture());
Authentication authentication = authenticationCaptor.getValue();
assertThat(authentication.getPrincipal()).isInstanceOf(OAuth2User.class);
}
// gh-5521
@@ -406,17 +372,19 @@ public class OAuth2LoginBeanDefinitionParserTests {
this.spring.configLocations(this.xml("SingleClientRegistration-WithCustomAuthorizationRequestResolver"))
.autowire();
this.mvc.perform(get("/oauth2/authorization/google")).andExpect(status().is3xxRedirection());
this.mvc.perform(get("/oauth2/authorization/google-login"))
.andExpect(status().is3xxRedirection());
verify(oauth2AuthorizationRequestResolver).resolve(any());
verify(authorizationRequestResolver).resolve(any());
}
// gh-5347
@Test
public void requestWhenMultipleClientsConfiguredThenRedirectDefaultLoginPage() throws Exception {
public void requestWhenMultiClientRegistrationThenRedirectDefaultLoginPage() throws Exception {
this.spring.configLocations(this.xml("MultiClientRegistration")).autowire();
this.mvc.perform(get("/")).andExpect(status().is3xxRedirection())
this.mvc.perform(get("/"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/login"));
}
@@ -424,7 +392,8 @@ public class OAuth2LoginBeanDefinitionParserTests {
public void requestWhenCustomLoginPageThenRedirectCustomLoginPage() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithCustomLoginPage")).autowire();
this.mvc.perform(get("/")).andExpect(status().is3xxRedirection())
this.mvc.perform(get("/"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/custom-login"));
}
@@ -434,7 +403,8 @@ public class OAuth2LoginBeanDefinitionParserTests {
throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithFormLogin")).autowire();
this.mvc.perform(get("/")).andExpect(status().is3xxRedirection())
this.mvc.perform(get("/"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/login"));
}
@@ -442,39 +412,41 @@ public class OAuth2LoginBeanDefinitionParserTests {
public void requestWhenCustomClientRegistrationRepositoryThenCalled() throws Exception {
this.spring.configLocations(this.xml("WithCustomClientRegistrationRepository")).autowire();
ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(clientRegistration);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, clientRegistration.getRegistrationId());
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/google").params(params));
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/code/" + clientRegistration.getRegistrationId()).params(params));
assertThat(MockUtil.isMock(clientRegistrationRepository)).isTrue();
verify(clientRegistrationRepository).findByRegistrationId("google-login");
Field field = oauth2LoginAuthenticationFilter.getClass().getDeclaredField("clientRegistrationRepository");
field.setAccessible(true);
Object fieldVal = field.get(oauth2LoginAuthenticationFilter);
assertThat(MockUtil.isMock(fieldVal)).isTrue();
assertThat(fieldVal).isSameAs(clientRegistrationRepository);
verify(clientRegistrationRepository).findByRegistrationId(clientRegistration.getRegistrationId());
}
@Test
public void requestWhenCustomAuthorizedClientRepositoryThenCalled() throws Exception {
this.spring.configLocations(this.xml("WithCustomAuthorizedClientRepository")).autowire();
ClientRegistration clientReg = TestClientRegistrations.clientRegistration().build();
when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(clientReg);
ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(clientRegistration);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, clientRegistration.getRegistrationId());
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
@@ -482,76 +454,26 @@ public class OAuth2LoginBeanDefinitionParserTests {
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/registration-id").params(params));
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/code/" + clientRegistration.getRegistrationId()).params(params));
assertThat(MockUtil.isMock(oauth2AuthorizedClientRepository)).isTrue();
verify(oauth2AuthorizedClientRepository).saveAuthorizedClient(any(), any(), any(), any());
Field field = oauth2LoginAuthenticationFilter.getClass().getDeclaredField("authorizedClientRepository");
field.setAccessible(true);
Object fieldVal = field.get(oauth2LoginAuthenticationFilter);
assertThat(MockUtil.isMock(fieldVal)).isTrue();
assertThat(fieldVal).isSameAs(oauth2AuthorizedClientRepository);
verify(authorizedClientRepository).saveAuthorizedClient(any(), any(), any(), any());
}
@Test
public void requestWhenCustomAuthorizedClientServiceThenCalled() throws Exception {
this.spring.configLocations(this.xml("WithCustomAuthorizedClientService")).autowire();
ClientRegistration clientReg = TestClientRegistrations.clientRegistration().build();
when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(clientReg);
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(clientRegistration);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/registration-id").params(params));
assertThat(MockUtil.isMock(oauth2AuthorizedClientService)).isTrue();
verify(oauth2AuthorizedClientService).saveAuthorizedClient(any(), any());
Field authorizedClientRepositoryField = oauth2LoginAuthenticationFilter.getClass()
.getDeclaredField("authorizedClientRepository");
authorizedClientRepositoryField.setAccessible(true);
Object authorizedClientRepositoryFieldVal = authorizedClientRepositoryField
.get(oauth2LoginAuthenticationFilter);
assertThat(authorizedClientRepositoryFieldVal)
.isInstanceOf(AuthenticatedPrincipalOAuth2AuthorizedClientRepository.class);
Field authorizedClientServiceField = authorizedClientRepositoryFieldVal.getClass()
.getDeclaredField("authorizedClientService");
authorizedClientServiceField.setAccessible(true);
Object authorizedClientServiceFieldVal = authorizedClientServiceField.get(authorizedClientRepositoryFieldVal);
assertThat(MockUtil.isMock(authorizedClientServiceFieldVal)).isTrue();
assertThat(authorizedClientServiceFieldVal).isSameAs(oauth2AuthorizedClientService);
}
@Test
public void requestWhenCustomAuthorizationRequestRepositoryThenCalled() throws Exception {
this.spring.configLocations(this.xml("WithCustomAuthorizationRequestRepository")).autowire();
ClientRegistration clientReg = TestClientRegistrations.clientRegistration().build();
when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(clientReg);
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, clientRegistration.getRegistrationId());
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
.attributes(attributes).build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authorizationRequest);
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
@@ -561,78 +483,13 @@ public class OAuth2LoginBeanDefinitionParserTests {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", "state");
this.mvc.perform(get("/login/oauth2/code/registration-id").params(params));
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/code/" + clientRegistration.getRegistrationId()).params(params));
assertThat(MockUtil.isMock(authorizationRequestRepository)).isTrue();
verify(authorizationRequestRepository).removeAuthorizationRequest(any(), any());
Field authorizationRequestRepositoryField = oauth2LoginAuthenticationFilter.getClass()
.getDeclaredField("authorizationRequestRepository");
authorizationRequestRepositoryField.setAccessible(true);
Object authorizationRequestRepositoryFieldVal = authorizationRequestRepositoryField
.get(oauth2LoginAuthenticationFilter);
assertThat(MockUtil.isMock(authorizationRequestRepositoryFieldVal)).isTrue();
assertThat(authorizationRequestRepositoryFieldVal).isSameAs(authorizationRequestRepository);
}
@Test
public void requestWhenCustomAuthenticationSuccessHandlerThenCalled() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithCustomAuthenticationHandler")).autowire();
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().build();
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
when(this.oauth2UserService.loadUser(any())).thenReturn(oauth2User);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, "google-login");
OAuth2AuthorizationRequest authRequest = TestOAuth2AuthorizationRequests.request().attributes(attributes)
.build();
when(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any())).thenReturn(authRequest);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authRequest.getState());
this.mvc.perform(get("/login/oauth2/code/google").params(params)).andExpect(status().is2xxSuccessful());
ArgumentCaptor<Authentication> authenticationCaptor = ArgumentCaptor.forClass(Authentication.class);
verify(authenticationSuccessHandler).onAuthenticationSuccess(any(), any(), authenticationCaptor.capture());
Authentication authenticationValue = authenticationCaptor.getValue();
assertThat(authenticationValue.getAuthorities()).hasSize(1);
assertThat(authenticationValue.getAuthorities()).first().isInstanceOf(SimpleGrantedAuthority.class)
.hasToString("ROLE_USER");
}
@Test
public void requestWhenCustomAuthenticationFailureHandlerThenCalled() throws Exception {
this.spring.configLocations(this.xml("SingleClientRegistration-WithCustomAuthenticationHandler")).autowire();
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", "state123");
this.mvc.perform(get("/login/oauth2/code/google").params(params)).andExpect(status().isIAmATeapot());
verify(authorizedClientService).saveAuthorizedClient(any(), any());
}
private String xml(String configName) {
return CONFIG_LOCATION_PREFIX + "-" + configName + ".xml";
}
public static class TeapotAuthenticationHandler
implements AuthenticationSuccessHandler, AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) {
response.setStatus(HttpStatus.I_AM_A_TEAPOT.value());
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
response.setStatus(HttpStatus.I_AM_A_TEAPOT.value());
}
}
}

View File

@@ -15,9 +15,9 @@
*/
package org.springframework.security.config.oauth2.client;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Map;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -33,13 +33,7 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.util.StringUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ClientRegistrationsBeanDefinitionParser}.
@@ -49,13 +43,24 @@ import okhttp3.mockwebserver.RecordedRequest;
public class ClientRegistrationsBeanDefinitionParserTests {
private static final String CONFIG_LOCATION_PREFIX = "classpath:org/springframework/security/config/oauth2/client/ClientRegistrationsBeanDefinitionParserTests";
@Rule
public final SpringTestRule spring = new SpringTestRule();
private static final String ISSUER_URI_XML_CONFIG = "<b:beans xmlns:b=\"http://www.springframework.org/schema/beans\"\n" +
"\t\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
"\t\txmlns=\"http://www.springframework.org/schema/security\"\n" +
"\t\txsi:schemaLocation=\"\n" +
"\t\t\thttp://www.springframework.org/schema/security\n" +
"\t\t\thttps://www.springframework.org/schema/security/spring-security.xsd\n" +
"\t\t\thttp://www.springframework.org/schema/beans\n" +
"\t\t\thttps://www.springframework.org/schema/beans/spring-beans.xsd\">\n" +
"\n" +
"\t<client-registrations>\n" +
"\t\t<client-registration registration-id=\"google-login\" client-id=\"google-client-id\" \n" +
"\t\t\t\t\t\t\t client-secret=\"google-client-secret\" provider-id=\"google\"/>\n" +
"\t\t<provider provider-id=\"google\" issuer-uri=\"${issuer-uri}\"/>\n" +
"\t</client-registrations>\n" +
"\n" +
"</b:beans>\n";
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
private static final String DEFAULT_RESPONSE =
private static final String OIDC_DISCOVERY_RESPONSE =
"{\n"
+ " \"authorization_endpoint\": \"https://example.com/o/oauth2/v2/auth\", \n"
+ " \"claims_supported\": [\n"
@@ -79,7 +84,7 @@ public class ClientRegistrationsBeanDefinitionParserTests {
+ " \"id_token_signing_alg_values_supported\": [\n"
+ " \"RS256\"\n"
+ " ], \n"
+ " \"issuer\": \"http://localhost:49259\", \n"
+ " \"issuer\": \"${issuer-uri}\", \n"
+ " \"jwks_uri\": \"https://example.com/oauth2/v3/certs\", \n"
+ " \"response_types_supported\": [\n"
+ " \"code\", \n"
@@ -110,71 +115,47 @@ public class ClientRegistrationsBeanDefinitionParserTests {
+ " \"userinfo_endpoint\": \"https://example.com/oauth2/v3/userinfo\"\n"
+ "}";
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
@Rule
public final SpringTestRule spring = new SpringTestRule();
private MockWebServer server;
@After
public void cleanup() throws Exception {
if (this.server != null) {
this.server.shutdown();
}
}
@Test
public void parseWhenIssuerUriConfiguredThenRequestConfigFromIssuer() throws Exception {
MockWebServer server = new MockWebServer();
ObjectMapper mapper = new ObjectMapper();
server.start(49259);
Map<String, Object> response = mapper.readValue(DEFAULT_RESPONSE, new TypeReference<Map<String, Object>>() {
});
final String responseBody = mapper.writeValueAsString(response);
this.server = new MockWebServer();
this.server.start();
String serverUrl = this.server.url("/").toString();
final Dispatcher oidcDispatcher = new Dispatcher() {
@Override
public MockResponse dispatch(RecordedRequest request) {
switch (request.getPath()) {
case "/issuer1/.well-known/openid-configuration":
case "/.well-known/openid-configuration":
return new MockResponse().setResponseCode(200).setBody(responseBody)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
}
return new MockResponse().setResponseCode(404);
}
};
String discoveryResponse = OIDC_DISCOVERY_RESPONSE.replace("${issuer-uri}", serverUrl);
this.server.enqueue(jsonResponse(discoveryResponse));
final Dispatcher oauthDispatcher = new Dispatcher() {
@Override
public MockResponse dispatch(RecordedRequest request) {
switch (request.getPath()) {
case "/.well-known/oauth-authorization-server/issuer1":
case "/.well-known/oauth-authorization-server":
return new MockResponse().setResponseCode(200).setBody(responseBody)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
}
return new MockResponse().setResponseCode(404);
}
};
server.setDispatcher(oidcDispatcher);
this.spring.configLocations(this.xml("FromIssuerUri")).autowire();
String contextConfig = ISSUER_URI_XML_CONFIG.replace("${issuer-uri}", serverUrl);
this.spring.context(contextConfig).autowire();
assertThat(clientRegistrationRepository).isInstanceOf(InMemoryClientRegistrationRepository.class);
testIssuerUriResponse(clientRegistrationRepository);
ClientRegistration googleRegistration = clientRegistrationRepository.findByRegistrationId("google-login");
assertThat(googleRegistration).isNotNull();
assertThat(googleRegistration.getRegistrationId()).isEqualTo("google-login");
assertThat(googleRegistration.getClientId()).isEqualTo("google-client-id");
assertThat(googleRegistration.getClientSecret()).isEqualTo("google-client-secret");
assertThat(googleRegistration.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.BASIC);
assertThat(googleRegistration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(googleRegistration.getRedirectUriTemplate()).isEqualTo("{baseUrl}/{action}/oauth2/code/{registrationId}");
assertThat(googleRegistration.getScopes()).isEqualTo(StringUtils.commaDelimitedListToSet("openid,profile,email"));
assertThat(googleRegistration.getClientName()).isEqualTo(serverUrl);
// test oauth
server.setDispatcher(oauthDispatcher);
this.spring.configLocations(this.xml("FromIssuerUri")).autowire();
testIssuerUriResponse(clientRegistrationRepository);
server.shutdown();
server.close();
}
private void testIssuerUriResponse(ClientRegistrationRepository clientRegistrationRepository) {
ClientRegistration googleLogin = clientRegistrationRepository.findByRegistrationId("google-login");
assertThat(googleLogin).isNotNull();
assertThat(googleLogin.getRegistrationId()).isEqualTo("google-login");
assertThat(googleLogin.getClientId()).isEqualTo("google-client-id");
assertThat(googleLogin.getClientSecret()).isEqualTo("google-client-secret");
assertThat(googleLogin.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.BASIC);
assertThat(googleLogin.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(googleLogin.getRedirectUriTemplate()).isEqualTo("{baseUrl}/login/oauth2/code/{registrationId}");
assertThat(googleLogin.getScopes()).isEqualTo(StringUtils.commaDelimitedListToSet("openid,profile,email"));
assertThat(googleLogin.getClientName()).isEqualTo("Google");
ProviderDetails googleProviderDetails = googleLogin.getProviderDetails();
ProviderDetails googleProviderDetails = googleRegistration.getProviderDetails();
assertThat(googleProviderDetails).isNotNull();
assertThat(googleProviderDetails.getAuthorizationUri()).isEqualTo("https://example.com/o/oauth2/v2/auth");
assertThat(googleProviderDetails.getTokenUri()).isEqualTo("https://example.com/oauth2/v4/token");
@@ -187,23 +168,23 @@ public class ClientRegistrationsBeanDefinitionParserTests {
}
@Test
public void parseWhenMultipleClientsConfiguredThenAvailableInRepository() throws Exception {
public void parseWhenMultipleClientsConfiguredThenAvailableInRepository() {
this.spring.configLocations(this.xml("MultiClientRegistration")).autowire();
assertThat(clientRegistrationRepository).isInstanceOf(InMemoryClientRegistrationRepository.class);
ClientRegistration googleLogin = clientRegistrationRepository.findByRegistrationId("google-login");
assertThat(googleLogin).isNotNull();
assertThat(googleLogin.getRegistrationId()).isEqualTo("google-login");
assertThat(googleLogin.getClientId()).isEqualTo("google-client-id");
assertThat(googleLogin.getClientSecret()).isEqualTo("google-client-secret");
assertThat(googleLogin.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.BASIC);
assertThat(googleLogin.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(googleLogin.getRedirectUriTemplate()).isEqualTo("{baseUrl}/login/oauth2/code/{registrationId}");
assertThat(googleLogin.getScopes()).isEqualTo(StringUtils.commaDelimitedListToSet("openid,profile,email"));
assertThat(googleLogin.getClientName()).isEqualTo("Google");
ClientRegistration googleRegistration = clientRegistrationRepository.findByRegistrationId("google-login");
assertThat(googleRegistration).isNotNull();
assertThat(googleRegistration.getRegistrationId()).isEqualTo("google-login");
assertThat(googleRegistration.getClientId()).isEqualTo("google-client-id");
assertThat(googleRegistration.getClientSecret()).isEqualTo("google-client-secret");
assertThat(googleRegistration.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.BASIC);
assertThat(googleRegistration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(googleRegistration.getRedirectUriTemplate()).isEqualTo("{baseUrl}/login/oauth2/code/{registrationId}");
assertThat(googleRegistration.getScopes()).isEqualTo(StringUtils.commaDelimitedListToSet("openid,profile,email"));
assertThat(googleRegistration.getClientName()).isEqualTo("Google");
ProviderDetails googleProviderDetails = googleLogin.getProviderDetails();
ProviderDetails googleProviderDetails = googleRegistration.getProviderDetails();
assertThat(googleProviderDetails).isNotNull();
assertThat(googleProviderDetails.getAuthorizationUri())
.isEqualTo("https://accounts.google.com/o/oauth2/v2/auth");
@@ -215,18 +196,18 @@ public class ClientRegistrationsBeanDefinitionParserTests {
assertThat(googleProviderDetails.getUserInfoEndpoint().getUserNameAttributeName()).isEqualTo("sub");
assertThat(googleProviderDetails.getJwkSetUri()).isEqualTo("https://www.googleapis.com/oauth2/v3/certs");
ClientRegistration githubLogin = clientRegistrationRepository.findByRegistrationId("github-login");
assertThat(githubLogin).isNotNull();
assertThat(githubLogin.getRegistrationId()).isEqualTo("github-login");
assertThat(githubLogin.getClientId()).isEqualTo("github-client-id");
assertThat(githubLogin.getClientSecret()).isEqualTo("github-client-secret");
assertThat(githubLogin.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.BASIC);
assertThat(githubLogin.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(githubLogin.getRedirectUriTemplate()).isEqualTo("{baseUrl}/login/oauth2/code/{registrationId}");
assertThat(googleLogin.getScopes()).isEqualTo(StringUtils.commaDelimitedListToSet("openid,profile,email"));
assertThat(githubLogin.getClientName()).isEqualTo("Github");
ClientRegistration githubRegistration = clientRegistrationRepository.findByRegistrationId("github-login");
assertThat(githubRegistration).isNotNull();
assertThat(githubRegistration.getRegistrationId()).isEqualTo("github-login");
assertThat(githubRegistration.getClientId()).isEqualTo("github-client-id");
assertThat(githubRegistration.getClientSecret()).isEqualTo("github-client-secret");
assertThat(githubRegistration.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.BASIC);
assertThat(githubRegistration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(githubRegistration.getRedirectUriTemplate()).isEqualTo("{baseUrl}/login/oauth2/code/{registrationId}");
assertThat(googleRegistration.getScopes()).isEqualTo(StringUtils.commaDelimitedListToSet("openid,profile,email"));
assertThat(githubRegistration.getClientName()).isEqualTo("Github");
ProviderDetails githubProviderDetails = githubLogin.getProviderDetails();
ProviderDetails githubProviderDetails = githubRegistration.getProviderDetails();
assertThat(githubProviderDetails).isNotNull();
assertThat(githubProviderDetails.getAuthorizationUri()).isEqualTo("https://github.com/login/oauth/authorize");
assertThat(githubProviderDetails.getTokenUri()).isEqualTo("https://github.com/login/oauth/access_token");
@@ -236,7 +217,13 @@ public class ClientRegistrationsBeanDefinitionParserTests {
assertThat(githubProviderDetails.getUserInfoEndpoint().getUserNameAttributeName()).isEqualTo("id");
}
private String xml(String configName) {
private static MockResponse jsonResponse(String json) {
return new MockResponse()
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody(json);
}
private static String xml(String configName) {
return CONFIG_LOCATION_PREFIX + "-" + configName + ".xml";
}
}