ExternalOAuthAuthenticationManager extends ExternalLoginAuthenticationManager<ExternalOAuthAuthenticationManager.AuthenticationData> { @Override public AuthenticationData getExternalAuthenticationDetails(Authentication authentication) { IdentityProvider provider = null; ExternalOAuthCodeToken codeToken = (ExternalOAuthCodeToken) authentication; if (isEmpty(codeToken.getOrigin())) { provider = resolveOriginProvider(codeToken.getIdToken()); codeToken.setOrigin(provider.getOriginKey()); } setOrigin(codeToken.getOrigin()); if (provider == null) { try { provider = getProviderProvisioning().retrieveByOrigin(getOrigin(), IdentityZoneHolder.get().getId()); } catch (EmptyResultDataAccessException e) { logger.info("No provider found for given origin"); throw new InsufficientAuthenticationException("Could not resolve identity provider with given origin."); } } if (provider != null && provider.getConfig() instanceof AbstractExternalOAuthIdentityProviderDefinition) { AuthenticationData authenticationData = new AuthenticationData(); AbstractExternalOAuthIdentityProviderDefinition config = (AbstractExternalOAuthIdentityProviderDefinition) provider.getConfig(); Map<String, Object> claims = getClaimsFromToken(codeToken, config); if (claims == null) { return null; } authenticationData.setClaims(claims); Map<String, Object> attributeMappings = config.getAttributeMappings(); String userNameAttributePrefix = (String) attributeMappings.get(USER_NAME_ATTRIBUTE_NAME); String username; if (StringUtils.hasText(userNameAttributePrefix)) { username = (String) claims.get(userNameAttributePrefix); logger.debug(String.format("Extracted username for claim: %s and username is: %s", userNameAttributePrefix, username)); } else { username = (String) claims.get(SUB); logger.debug(String.format("Extracted username for claim: %s and username is: %s", SUB, username)); } if (!hasText(username)) { throw new InsufficientAuthenticationException("Unable to map claim to a username"); } authenticationData.setUsername(username); List<? extends GrantedAuthority> authorities = extractExternalOAuthUserAuthorities(attributeMappings, claims); authorities = mapAuthorities(codeToken.getOrigin(), authorities); authenticationData.setAuthorities(authorities); ofNullable(attributeMappings).ifPresent(map -> authenticationData.setAttributeMappings(new HashMap<>(map))); return authenticationData; } logger.debug("No identity provider found for origin:"+getOrigin()+" and zone:"+IdentityZoneHolder.get().getId()); return null; } ExternalOAuthAuthenticationManager(IdentityProviderProvisioning providerProvisioning,
                                              RestTemplate trustingRestTemplate,
                                              RestTemplate nonTrustingRestTemplate,
                                              TokenEndpointBuilder tokenEndpointBuilder,
                                              KeyInfoService keyInfoService); @Override String getOrigin(); @Override void setOrigin(String origin); IdentityProvider resolveOriginProvider(String idToken); @Override AuthenticationData getExternalAuthenticationDetails(Authentication authentication); RestTemplate getRestTemplate(AbstractExternalOAuthIdentityProviderDefinition config); void setTokenEndpointBuilder(TokenEndpointBuilder tokenEndpointBuilder); KeyInfoService getKeyInfoService(); static Logger logger; }
@Test public void getExternalAuthenticationDetails_whenProviderHasSigningKey_throwsWhenIdTokenCannotBeValidated() { expectedException.expect(InvalidTokenException.class); expectedException.expectMessage("Could not verify token signature."); Map<String, Object> header = map( entry(ALG, "HS256"), entry(KID, "oidc-provider-key") ); Signer signer = new RsaSigner(changedOidcProviderTokenSigningKey); Map<String, Object> claims = map( entry(EMAIL, "someuser@google.com") ); IdentityZoneHolder.get().getConfig().getTokenPolicy().setKeys(Collections.singletonMap("uaa-key", uaaIdentityZoneTokenSigningKey)); String idTokenJwt = UaaTokenUtils.constructToken(header, claims, signer); ExternalOAuthCodeToken oidcAuthentication = new ExternalOAuthCodeToken("thecode", origin, "http: authManager.getExternalAuthenticationDetails(oidcAuthentication); }
@Test public void getExternalAuthenticationDetails_whenProviderIssuerMatchesUaaIssuer_throwsWhenIdTokenCannotBeValidated() { oidcConfig.setIssuer(tokenEndpointBuilder.getTokenEndpoint(IdentityZoneHolder.get())); expectedException.expect(InvalidTokenException.class); expectedException.expectMessage("Could not verify token signature."); Map<String, Object> header = map( entry(ALG, "HS256"), entry(KID, "uaa-key") ); Signer signer = new RsaSigner(oidcProviderTokenSigningKey); Map<String, Object> claims = map( entry(EMAIL, "someuser@google.com") ); IdentityZoneHolder.get().getConfig().getTokenPolicy().setKeys(Collections.singletonMap("uaa-key", uaaIdentityZoneTokenSigningKey)); String idTokenJwt = UaaTokenUtils.constructToken(header, claims, signer); ExternalOAuthCodeToken oidcAuthentication = new ExternalOAuthCodeToken(null, origin, "http: authManager.getExternalAuthenticationDetails(oidcAuthentication); }
@Test public void getExternalAuthenticationDetails_doesNotThrowWhenIdTokenIsValid() { Map<String, Object> header = map( entry(ALG, "HS256"), entry(KID, "oidc-provider-key") ); Signer signer = new RsaSigner(oidcProviderTokenSigningKey); Map<String, Object> claims = map( entry(EMAIL, "someuser@google.com"), entry(ISS, oidcConfig.getIssuer()), entry(AUD, "uaa-relying-party"), entry(EXP, ((int) (System.currentTimeMillis()/1000L)) + 60), entry(SUB, "abc-def-asdf") ); IdentityZoneHolder.get().getConfig().getTokenPolicy().setKeys(Collections.singletonMap("uaa-key", uaaIdentityZoneTokenSigningKey)); String idTokenJwt = UaaTokenUtils.constructToken(header, claims, signer); ExternalOAuthCodeToken oidcAuthentication = new ExternalOAuthCodeToken(null, origin, "http: authManager.getExternalAuthenticationDetails(oidcAuthentication); }
@Test public void getExternalAuthenticationDetails_whenUaaToken_doesNotThrowWhenIdTokenIsValid() { oidcConfig.setIssuer(tokenEndpointBuilder.getTokenEndpoint(IdentityZoneHolder.get())); Map<String, Object> header = map( entry(ALG, "HS256"), entry(KID, "uaa-key") ); Signer signer = new RsaSigner(uaaIdentityZoneTokenSigningKey); Map<String, Object> claims = map( entry(EMAIL, "someuser@google.com"), entry(ISS, oidcConfig.getIssuer()), entry(AUD, "uaa-relying-party"), entry(EXP, ((int) (System.currentTimeMillis()/1000L)) + 60), entry(SUB, "abc-def-asdf") ); IdentityZoneHolder.get().getConfig().getTokenPolicy().setKeys(Collections.singletonMap("uaa-key", uaaIdentityZoneTokenSigningKey)); String idTokenJwt = UaaTokenUtils.constructToken(header, claims, signer); ExternalOAuthCodeToken oidcAuthentication = new ExternalOAuthCodeToken("thecode", origin, "http: authManager.getExternalAuthenticationDetails(oidcAuthentication); }