@Override public Mono<OidcUser> loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { Assert.notNull(userRequest, "userRequest cannot be null"); return getUserInfo(userRequest) .map(userInfo -> new OidcUserAuthority(userRequest.getIdToken(), userInfo)) .defaultIfEmpty(new OidcUserAuthority(userRequest.getIdToken(), null)) .map(authority -> { OidcUserInfo userInfo = authority.getUserInfo(); Set<GrantedAuthority> authorities = new HashSet<>(); authorities.add(authority); String userNameAttributeName = userRequest.getClientRegistration() .getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName(); if (StringUtils.hasText(userNameAttributeName)) { return new DefaultOidcUser(authorities, userRequest.getIdToken(), userInfo, userNameAttributeName); } else { return new DefaultOidcUser(authorities, userRequest.getIdToken(), userInfo); } }); }
private Mono<OidcUserInfo> getUserInfo(OidcUserRequest userRequest) { if (!OidcUserRequestUtils.shouldRetrieveUserInfo(userRequest)) { return Mono.empty(); } return this.oauth2UserService.loadUser(userRequest) .map(OAuth2User::getAttributes) .map(OidcUserInfo::new) .doOnNext(userInfo -> { String subject = userInfo.getSubject(); if (subject == null || !subject.equals(userRequest.getIdToken().getSubject())) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_USER_INFO_RESPONSE_ERROR_CODE); throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); } }); }
@Test public void constructorWhenAllParametersProvidedAndValidThenCreated() { OidcUserRequest userRequest = new OidcUserRequest( this.clientRegistration, this.accessToken, this.idToken, this.additionalParameters); assertThat(userRequest.getClientRegistration()).isEqualTo(this.clientRegistration); assertThat(userRequest.getAccessToken()).isEqualTo(this.accessToken); assertThat(userRequest.getIdToken()).isEqualTo(this.idToken); assertThat(userRequest.getAdditionalParameters()).containsAllEntriesOf(this.additionalParameters); } }
if (!userInfo.getSubject().equals(userRequest.getIdToken().getSubject())) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_USER_INFO_RESPONSE_ERROR_CODE); throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); new OidcUserAuthority(userRequest.getIdToken(), userInfo)); .getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName(); if (StringUtils.hasText(userNameAttributeName)) { user = new DefaultOidcUser(authorities, userRequest.getIdToken(), userInfo, userNameAttributeName); } else { user = new DefaultOidcUser(authorities, userRequest.getIdToken(), userInfo);
@Override public Mono<OidcUser> loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { Assert.notNull(userRequest, "userRequest cannot be null"); return getUserInfo(userRequest) .map(userInfo -> new OidcUserAuthority(userRequest.getIdToken(), userInfo)) .defaultIfEmpty(new OidcUserAuthority(userRequest.getIdToken(), null)) .map(authority -> { OidcUserInfo userInfo = authority.getUserInfo(); Set<GrantedAuthority> authorities = new HashSet<>(); authorities.add(authority); String userNameAttributeName = userRequest.getClientRegistration() .getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName(); if (StringUtils.hasText(userNameAttributeName)) { return new DefaultOidcUser(authorities, userRequest.getIdToken(), userInfo, userNameAttributeName); } else { return new DefaultOidcUser(authorities, userRequest.getIdToken(), userInfo); } }); }
/** * Augments {@link OidcUserService#loadUser(OidcUserRequest)} to add authorities * provided by Keycloak. * * Needed because {@link OidcUserService#loadUser(OidcUserRequest)} (currently) * does not provide a hook for adding custom authorities from a * {@link OidcUserRequest}. */ @Override public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { OidcUser user = super.loadUser(userRequest); Set<GrantedAuthority> authorities = new LinkedHashSet<>(); authorities.addAll(user.getAuthorities()); authorities.addAll(extractKeycloakAuthorities(userRequest)); return new DefaultOidcUser(authorities, userRequest.getIdToken(), user.getUserInfo(), "preferred_username"); }
private Mono<OidcUserInfo> getUserInfo(OidcUserRequest userRequest) { if (!OidcUserRequestUtils.shouldRetrieveUserInfo(userRequest)) { return Mono.empty(); } return this.oauth2UserService.loadUser(userRequest) .map(OAuth2User::getAttributes) .map(OidcUserInfo::new) .doOnNext(userInfo -> { String subject = userInfo.getSubject(); if (subject == null || !subject.equals(userRequest.getIdToken().getSubject())) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_USER_INFO_RESPONSE_ERROR_CODE); throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); } }); }
if (!userInfo.getSubject().equals(userRequest.getIdToken().getSubject())) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_USER_INFO_RESPONSE_ERROR_CODE); throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); new OidcUserAuthority(userRequest.getIdToken(), userInfo)); .getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName(); if (StringUtils.hasText(userNameAttributeName)) { user = new DefaultOidcUser(authorities, userRequest.getIdToken(), userInfo, userNameAttributeName); } else { user = new DefaultOidcUser(authorities, userRequest.getIdToken(), userInfo);
@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; }
@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; }