|
7 | 7 | import org.apache.commons.lang3.RandomStringUtils; |
8 | 8 | import org.cloudfoundry.identity.uaa.authentication.AccountNotPreCreatedException; |
9 | 9 | import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication; |
| 10 | +import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; |
10 | 11 | import org.cloudfoundry.identity.uaa.authentication.event.IdentityProviderAuthenticationSuccessEvent; |
11 | 12 | import org.cloudfoundry.identity.uaa.authentication.manager.ExternalGroupAuthorizationEvent; |
12 | 13 | import org.cloudfoundry.identity.uaa.authentication.manager.InvitedUserAuthenticatedEvent; |
|
95 | 96 | import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
96 | 97 | import static org.assertj.core.api.Assertions.assertThatThrownBy; |
97 | 98 | import static org.assertj.core.api.Assertions.fail; |
| 99 | +import static org.cloudfoundry.identity.uaa.constants.OriginKeys.OAUTH20; |
98 | 100 | import static org.cloudfoundry.identity.uaa.oauth.token.ClaimConstants.ISS; |
99 | 101 | import static org.cloudfoundry.identity.uaa.provider.ExternalIdentityProviderDefinition.GROUP_ATTRIBUTE_NAME; |
100 | 102 | import static org.cloudfoundry.identity.uaa.provider.ExternalIdentityProviderDefinition.USER_NAME_ATTRIBUTE_NAME; |
|
109 | 111 | import static org.mockito.Mockito.eq; |
110 | 112 | import static org.mockito.Mockito.mock; |
111 | 113 | import static org.mockito.Mockito.never; |
| 114 | +import static org.mockito.Mockito.reset; |
112 | 115 | import static org.mockito.Mockito.same; |
113 | 116 | import static org.mockito.Mockito.spy; |
114 | 117 | import static org.mockito.Mockito.times; |
@@ -515,6 +518,55 @@ void discoveryURL_is_used() throws MalformedURLException { |
515 | 518 |
|
516 | 519 | } |
517 | 520 |
|
| 521 | + @Test |
| 522 | + void oauth20_flow_works_with_non_jwt_token() throws Exception { |
| 523 | + String userInfoResponse = """ |
| 524 | + { |
| 525 | + "login": "octocat", |
| 526 | + "id": 1, |
| 527 | + "type": "User", |
| 528 | + "site_admin": false, |
| 529 | + "name": "monalisa octocat", |
| 530 | + "company": "GitHub", |
| 531 | + |
| 532 | + }"""; |
| 533 | + |
| 534 | + CompositeToken accessToken = getCompositeAccessToken(); |
| 535 | + accessToken.setIdTokenValue(null); //DOES NOT EXIST FOR OAUTH2.0 |
| 536 | + String oauth2TokenResponse = JsonUtils.writeValueAsString(accessToken); |
| 537 | + |
| 538 | + //UAA exchanges the code for a token |
| 539 | + mockUaaServer.expect(requestTo("http://localhost/oauth/token")) |
| 540 | + .andExpect(header("Authorization", "Basic " + new String(Base64.encodeBase64("identity:identitysecret".getBytes())))) |
| 541 | + .andExpect(header("Accept", "application/json")) |
| 542 | + .andExpect(content().string(containsString("grant_type=authorization_code"))) |
| 543 | + .andExpect(content().string(containsString("code=the_code"))) |
| 544 | + .andExpect(content().string(containsString("redirect_uri=http%3A%2F%2Flocalhost%2Fcallback%2Fthe_origin"))) |
| 545 | + .andExpect(content().string(containsString("response_type=code"))) |
| 546 | + .andRespond(withStatus(OK).contentType(APPLICATION_JSON).body(oauth2TokenResponse)); |
| 547 | + |
| 548 | + //UAA retrieves user info using an access token |
| 549 | + mockUaaServer.expect(requestTo(config.getUserInfoUrl().toString())) |
| 550 | + .andRespond(withStatus(OK).contentType(APPLICATION_JSON).body(userInfoResponse)); |
| 551 | + |
| 552 | + IdentityProvider<RawExternalOAuthIdentityProviderDefinition> identityProvider = getOauth20Provider(); |
| 553 | + identityProvider.getConfig().setResponseType("code"); |
| 554 | + reset(provisioning); |
| 555 | + when(provisioning.retrieveByOrigin(eq(ORIGIN), anyString())).thenReturn(identityProvider); |
| 556 | + |
| 557 | + addTheUserOnAuth(); |
| 558 | + |
| 559 | + Authentication authentication = externalOAuthAuthenticationManager.authenticate(xCodeToken); |
| 560 | + assertThat(authentication).isNotNull(); |
| 561 | + assertThat(authentication.getPrincipal()).isInstanceOf(UaaPrincipal.class); |
| 562 | + UaaPrincipal principal = (UaaPrincipal) authentication.getPrincipal(); |
| 563 | + assertThat(principal).isNotNull(); |
| 564 | + assertThat(principal.getName()).isEqualTo("octocat"); |
| 565 | + assertThat( principal. getEmail()). isEqualTo( "[email protected]"); |
| 566 | + mockUaaServer.verify(); |
| 567 | + |
| 568 | + } |
| 569 | + |
518 | 570 | @Test |
519 | 571 | void clientAuthInBody_is_used() { |
520 | 572 | config.setClientAuthInBody(true); |
@@ -1291,6 +1343,31 @@ private IdentityProvider<OIDCIdentityProviderDefinition> getProvider() { |
1291 | 1343 | return identityProvider; |
1292 | 1344 | } |
1293 | 1345 |
|
| 1346 | + private IdentityProvider<RawExternalOAuthIdentityProviderDefinition> getOauth20Provider() throws Exception { |
| 1347 | + RawExternalOAuthIdentityProviderDefinition config = new RawExternalOAuthIdentityProviderDefinition() |
| 1348 | + .setAuthUrl(URI.create("http://localhost/oauth/authorize").toURL()) |
| 1349 | + .setTokenUrl(URI.create("http://localhost/oauth/token").toURL()) |
| 1350 | + .setIssuer("http://localhost/oauth/token") |
| 1351 | + .setShowLinkText(true) |
| 1352 | + .setLinkText("My oauth20 Provider") |
| 1353 | + .setRelyingPartyId("identity") |
| 1354 | + .setRelyingPartySecret("identitysecret") |
| 1355 | + .setUserInfoUrl(URI.create("http://localhost/userinfo").toURL()) |
| 1356 | + .setTokenKey(PUBLIC_KEY); |
| 1357 | + config.setExternalGroupsWhitelist(Collections.singletonList("*")); |
| 1358 | + attributeMappings.put(USER_NAME_ATTRIBUTE_NAME, "login"); |
| 1359 | + config.setAttributeMappings(attributeMappings); |
| 1360 | + config.setResponseType("code"); |
| 1361 | + |
| 1362 | + IdentityProvider<RawExternalOAuthIdentityProviderDefinition> identityProvider = new IdentityProvider<>(); |
| 1363 | + identityProvider.setName("my oauth20 provider"); |
| 1364 | + identityProvider.setIdentityZoneId(OriginKeys.UAA); |
| 1365 | + identityProvider.setType(OAUTH20); |
| 1366 | + identityProvider.setConfig(config); |
| 1367 | + identityProvider.setOriginKey(ORIGIN); |
| 1368 | + return identityProvider; |
| 1369 | + } |
| 1370 | + |
1294 | 1371 | private void testTokenHasAuthoritiesFromIdTokenRoles() { |
1295 | 1372 | attributeMappings.put(GROUP_ATTRIBUTE_NAME, "scope"); |
1296 | 1373 | mockToken(); |
|
0 commit comments