@Test public void loadUserWhenUserRequestIsNullThenThrowIllegalArgumentException() { this.exception.expect(IllegalArgumentException.class); this.userService.loadUser(null); }
OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService = this.userInfoEndpointConfig.oidcUserService; if (oidcUserService == null) { oidcUserService = new OidcUserService();
Assert.notNull(userRequest, "userRequest cannot be null"); OidcUserInfo userInfo = null; if (this.shouldRetrieveUserInfo(userRequest)) { OAuth2User oauth2User = this.oauth2UserService.loadUser(userRequest); userInfo = new OidcUserInfo(oauth2User.getAttributes());
@Override public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { final OidcUserService delegate = new OidcUserService(); // Delegate to the default implementation for loading a user OidcUser oidcUser = delegate.loadUser(userRequest); final OidcIdToken idToken = userRequest.getIdToken(); final String graphApiToken; final Set<GrantedAuthority> mappedAuthorities; try { // https://github.com/MicrosoftDocs/azure-docs/issues/8121#issuecomment-387090099 // In AAD App Registration configure oauth2AllowImplicitFlow to true final ClientRegistration registration = userRequest.getClientRegistration(); final ClientCredential credential = new ClientCredential(registration.getClientId(), registration.getClientSecret()); final AzureADGraphClient graphClient = new AzureADGraphClient(credential, aadAuthProps, serviceEndpointsProps); graphApiToken = graphClient.acquireTokenForGraphApi(idToken.getTokenValue(), aadAuthProps.getTenantId()).getAccessToken(); mappedAuthorities = graphClient.getGrantedAuthorities(graphApiToken); } catch (MalformedURLException e) { throw wrapException(INVALID_REQUEST, "Failed to acquire token for Graph API.", null, e); } catch (ServiceUnavailableException | InterruptedException | ExecutionException e) { throw wrapException(SERVER_ERROR, "Failed to acquire token for Graph API.", null, e); } catch (IOException e) { throw wrapException(SERVER_ERROR, "Failed to map group to authorities.", null, e); } // Create a copy of oidcUser but use the mappedAuthorities instead oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), getUserNameAttrName(userRequest)); return oidcUser; }
@Test public void setOauth2UserServiceWhenNullThenThrowIllegalArgumentException() { assertThatThrownBy(() -> this.userService.setOauth2UserService(null)) .isInstanceOf(IllegalArgumentException.class); }
@Override public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { final OidcUserService delegate = new OidcUserService(); // Delegate to the default implementation for loading a user OidcUser oidcUser = delegate.loadUser(userRequest); final OidcIdToken idToken = userRequest.getIdToken(); final String graphApiToken; final Set<GrantedAuthority> mappedAuthorities; try { // https://github.com/MicrosoftDocs/azure-docs/issues/8121#issuecomment-387090099 // In AAD App Registration configure oauth2AllowImplicitFlow to true final ClientRegistration registration = userRequest.getClientRegistration(); final ClientCredential credential = new ClientCredential(registration.getClientId(), registration.getClientSecret()); final AzureADGraphClient graphClient = new AzureADGraphClient(credential, aadAuthProps, serviceEndpointsProps); graphApiToken = graphClient.acquireTokenForGraphApi(idToken.getTokenValue(), aadAuthProps.getTenantId()).getAccessToken(); mappedAuthorities = graphClient.getGrantedAuthorities(graphApiToken); } catch (MalformedURLException e) { throw wrapException(INVALID_REQUEST, "Failed to acquire token for Graph API.", null, e); } catch (ServiceUnavailableException | InterruptedException | ExecutionException e) { throw wrapException(SERVER_ERROR, "Failed to acquire token for Graph API.", null, e); } catch (IOException e) { throw wrapException(SERVER_ERROR, "Failed to map group to authorities.", null, e); } // Create a copy of oidcUser but use the mappedAuthorities instead oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), getUserNameAttrName(userRequest)); return oidcUser; }
@Before public void setup() throws Exception { this.server = new MockWebServer(); this.server.start(); this.clientRegistrationBuilder = clientRegistration() .userInfoUri(null) .userInfoAuthenticationMethod(AuthenticationMethod.HEADER) .userNameAttributeName(StandardClaimNames.SUB); this.accessToken = scopes(OidcScopes.OPENID, OidcScopes.PROFILE); Map<String, Object> idTokenClaims = new HashMap<>(); idTokenClaims.put(IdTokenClaimNames.ISS, "https://provider.com"); idTokenClaims.put(IdTokenClaimNames.SUB, "subject1"); this.idToken = new OidcIdToken("access-token", Instant.MIN, Instant.MAX, idTokenClaims); this.userService.setOauth2UserService(new DefaultOAuth2UserService()); }
@Test public void loadUserWhenAuthorizedScopesDoesNotContainUserInfoScopesThenUserInfoEndpointNotRequested() { ClientRegistration clientRegistration = this.clientRegistrationBuilder .userInfoUri("http://provider.com/user").build(); Set<String> authorizedScopes = new LinkedHashSet<>(Arrays.asList("scope1", "scope2")); OAuth2AccessToken accessToken = new OAuth2AccessToken( OAuth2AccessToken.TokenType.BEARER, "access-token", Instant.MIN, Instant.MAX, authorizedScopes); OidcUser user = this.userService.loadUser( new OidcUserRequest(clientRegistration, accessToken, this.idToken)); assertThat(user.getUserInfo()).isNull(); }
OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService = this.userInfoEndpointConfig.oidcUserService; if (oidcUserService == null) { oidcUserService = new OidcUserService();
Assert.notNull(userRequest, "userRequest cannot be null"); OidcUserInfo userInfo = null; if (this.shouldRetrieveUserInfo(userRequest)) { OAuth2User oauth2User = this.oauth2UserService.loadUser(userRequest); userInfo = new OidcUserInfo(oauth2User.getAttributes());
@Test public void loadUserWhenUserInfoUriIsNullThenUserInfoEndpointNotRequested() { OidcUser user = this.userService.loadUser( new OidcUserRequest(this.clientRegistrationBuilder.build(), this.accessToken, this.idToken)); assertThat(user.getUserInfo()).isNull(); }
OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService = this.userInfoEndpointConfig.oidcUserService; if (oidcUserService == null) { oidcUserService = new OidcUserService();
.userInfoUri(userInfoUri).build(); OidcUser user = this.userService.loadUser( new OidcUserRequest(clientRegistration, this.accessToken, this.idToken));
@Test public void loadUserWhenUserInfoUriInvalidThenThrowOAuth2AuthenticationException() { this.exception.expect(OAuth2AuthenticationException.class); this.exception.expectMessage(containsString("[invalid_user_info_response] An error occurred while attempting to retrieve the UserInfo Resource")); String userInfoUri = "http://invalid-provider.com/user"; ClientRegistration clientRegistration = this.clientRegistrationBuilder .userInfoUri(userInfoUri).build(); this.userService.loadUser(new OidcUserRequest(clientRegistration, this.accessToken, this.idToken)); }
@Test public void loadUserWhenAuthenticationMethodHeaderSuccessResponseThenHttpMethodGet() throws Exception { String userInfoResponse = "{\n" + " \"sub\": \"subject1\",\n" + " \"name\": \"first last\",\n" + " \"given_name\": \"first\",\n" + " \"family_name\": \"last\",\n" + " \"preferred_username\": \"user1\",\n" + " \"email\": \"user1@example.com\"\n" + "}\n"; this.server.enqueue(jsonResponse(userInfoResponse)); String userInfoUri = this.server.url("/user").toString(); ClientRegistration clientRegistration = this.clientRegistrationBuilder .userInfoUri(userInfoUri).build(); this.userService.loadUser(new OidcUserRequest(clientRegistration, this.accessToken, this.idToken)); RecordedRequest request = this.server.takeRequest(); assertThat(request.getMethod()).isEqualTo(HttpMethod.GET.name()); assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON_VALUE); assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer " + this.accessToken.getTokenValue()); }
@Test public void loadUserWhenUserInfoSuccessResponseAndUserInfoSubjectNotSameAsIdTokenSubjectThenThrowOAuth2AuthenticationException() { this.exception.expect(OAuth2AuthenticationException.class); this.exception.expectMessage(containsString("invalid_user_info_response")); String userInfoResponse = "{\n" + " \"sub\": \"other-subject\"\n" + "}\n"; this.server.enqueue(jsonResponse(userInfoResponse)); String userInfoUri = this.server.url("/user").toString(); ClientRegistration clientRegistration = this.clientRegistrationBuilder .userInfoUri(userInfoUri).build(); this.userService.loadUser(new OidcUserRequest(clientRegistration, this.accessToken, this.idToken)); }
@Test public void loadUserWhenUserInfoSuccessResponseThenAcceptHeaderJson() throws Exception { String userInfoResponse = "{\n" + " \"sub\": \"subject1\",\n" + " \"name\": \"first last\",\n" + " \"given_name\": \"first\",\n" + " \"family_name\": \"last\",\n" + " \"preferred_username\": \"user1\",\n" + " \"email\": \"user1@example.com\"\n" + "}\n"; this.server.enqueue(jsonResponse(userInfoResponse)); String userInfoUri = this.server.url("/user").toString(); ClientRegistration clientRegistration = this.clientRegistrationBuilder .userInfoUri(userInfoUri).build(); this.userService.loadUser(new OidcUserRequest(clientRegistration, this.accessToken, this.idToken)); assertThat(this.server.takeRequest(1, TimeUnit.SECONDS).getHeader(HttpHeaders.ACCEPT)) .isEqualTo(MediaType.APPLICATION_JSON_VALUE); }
@Test public void loadUserWhenCustomUserNameAttributeNameThenGetNameReturnsCustomUserName() { String userInfoResponse = "{\n" + " \"sub\": \"subject1\",\n" + " \"name\": \"first last\",\n" + " \"given_name\": \"first\",\n" + " \"family_name\": \"last\",\n" + " \"preferred_username\": \"user1\",\n" + " \"email\": \"user1@example.com\"\n" + "}\n"; this.server.enqueue(jsonResponse(userInfoResponse)); String userInfoUri = this.server.url("/user").toString(); ClientRegistration clientRegistration = this.clientRegistrationBuilder .userInfoUri(userInfoUri) .userNameAttributeName(StandardClaimNames.EMAIL).build(); OidcUser user = this.userService.loadUser( new OidcUserRequest(clientRegistration, this.accessToken, this.idToken)); assertThat(user.getName()).isEqualTo("user1@example.com"); }
@Test public void loadUserWhenServerErrorThenThrowOAuth2AuthenticationException() { this.exception.expect(OAuth2AuthenticationException.class); this.exception.expectMessage(containsString("[invalid_user_info_response] An error occurred while attempting to retrieve the UserInfo Resource: 500 Server Error")); this.server.enqueue(new MockResponse().setResponseCode(500)); String userInfoUri = server.url("/user").toString(); ClientRegistration clientRegistration = this.clientRegistrationBuilder .userInfoUri(userInfoUri).build(); this.userService.loadUser(new OidcUserRequest(clientRegistration, this.accessToken, this.idToken)); }
@Test public void loadUserWhenAuthenticationMethodFormSuccessResponseThenHttpMethodPost() throws Exception { String userInfoResponse = "{\n" + " \"sub\": \"subject1\",\n" + " \"name\": \"first last\",\n" + " \"given_name\": \"first\",\n" + " \"family_name\": \"last\",\n" + " \"preferred_username\": \"user1\",\n" + " \"email\": \"user1@example.com\"\n" + "}\n"; this.server.enqueue(jsonResponse(userInfoResponse)); String userInfoUri = this.server.url("/user").toString(); ClientRegistration clientRegistration = this.clientRegistrationBuilder .userInfoUri(userInfoUri) .userInfoAuthenticationMethod(AuthenticationMethod.FORM).build(); this.userService.loadUser(new OidcUserRequest(clientRegistration, this.accessToken, this.idToken)); RecordedRequest request = this.server.takeRequest(); assertThat(request.getMethod()).isEqualTo(HttpMethod.POST.name()); assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON_VALUE); assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).contains(MediaType.APPLICATION_FORM_URLENCODED_VALUE); assertThat(request.getBody().readUtf8()).isEqualTo("access_token=" + this.accessToken.getTokenValue()); }