@@ -427,6 +427,63 @@ void shadowUserNameDefaultsToOIDCSubjectClaim() {
427427 assertThat (shadowUser .getUserName ()).isEqualTo (expectedUsername );
428428 }
429429
430+ @ Test
431+ void claimsComeFromUserInfoEndpoint () {
432+ AbstractExternalOAuthIdentityProviderDefinition <?> oldConfig = identityProvider .getConfig ();
433+ Map <String , Object > attributeMappings = new HashMap <>(identityProvider .getConfig ().getAttributeMappings ());
434+ attributeMappings .remove (USER_NAME_ATTRIBUTE_NAME );
435+ oldConfig .setAttributeMappings (attributeMappings );
436+ oldConfig .setLinkText ("My Oauth2.0 Provider" );
437+ //change the type so that we will use the /userinfo endpoint
438+ identityProvider .setType (OriginKeys .OAUTH20 );
439+ updateProvider ();
440+
441+ webDriver .get (zoneUrl );
442+ webDriver .clickAndWait (By .linkText (oldConfig .getLinkText ()));
443+
444+ webDriver .findElement (By .name ("username" )).clear ();
445+ webDriver .findElement (By .name ("username" )).sendKeys (testAccounts .getUserName ());
446+ webDriver .findElement (By .name ("password" )).sendKeys (testAccounts .getPassword ());
447+ webDriver .clickAndWait (By .xpath ("//input[@value='Sign in']" ));
448+
449+ webDriver .get (baseUrl );
450+ Cookie cookie = webDriver .manage ().getCookieNamed ("JSESSIONID" );
451+
452+ ServerRunningExtension localhostServerRunning = ServerRunningExtension .connect ();
453+ localhostServerRunning .setHostName ("localhost" );
454+
455+ String clientId = "client" + new RandomValueStringGenerator (5 ).generate ();
456+ UaaClientDetails client = new UaaClientDetails (clientId , null , "openid" , GRANT_TYPE_AUTHORIZATION_CODE , "openid" , baseUrl );
457+ client .setClientSecret ("clientsecret" );
458+ client .setAutoApproveScopes (Collections .singletonList ("true" ));
459+ IntegrationTestUtils .createClient (adminToken , baseUrl , client );
460+
461+ Map <String , String > authCodeTokenResponse = IntegrationTestUtils .getAuthorizationCodeTokenMap (localhostServerRunning ,
462+ clientId ,
463+ "clientsecret" ,
464+ null ,
465+ null ,
466+ "token id_token" ,
467+ cookie .getValue (),
468+ baseUrl ,
469+ null ,
470+ false );
471+
472+ //validate that we have an ID token, and that it contains costCenter and manager values
473+ String idToken = authCodeTokenResponse .get ("id_token" );
474+ assertThat (idToken ).isNotNull ();
475+
476+ Jwt idTokenClaims = JwtHelper .decode (idToken );
477+ Map <String , Object > claims = JsonUtils .readValue (idTokenClaims .getClaims (), new TypeReference <>() {});
478+ String expectedUsername = (String ) claims .get (SUB );
479+
480+ String anAdminToken = IntegrationTestUtils .getClientCredentialsToken (zoneUrl , zoneClient .getClientId (), zoneClient .getClientSecret ());
481+ ScimUser shadowUser = IntegrationTestUtils .getUser (anAdminToken , zoneUrl , identityProvider .getOriginKey (), expectedUsername );
482+ assertThat (shadowUser .getUserName ()).isEqualTo (expectedUsername );
483+ //there is no 'scope' attribute exposed on the /userinfo endpoint in this test.
484+ assertThat (shadowUser .getGroups ().stream ().map (g -> g .getDisplay ())).doesNotContain (createdGroup .getDisplayName ());
485+ }
486+
430487 @ Test
431488 void successfulLoginWithOIDC_and_SAML_Provider_PlusRefreshRotation () throws Exception {
432489 SamlIdentityProviderDefinition saml = IntegrationTestUtils .createSimplePHPSamlIDP ("simplesamlphp" , OriginKeys .UAA , samlServerConfig .getSamlServerUrl ());
0 commit comments