From 790fdc91ac0b302a8a1b949e2f9bda4d9ea0d264 Mon Sep 17 00:00:00 2001 From: Hongchol Sinn Date: Tue, 12 Dec 2023 11:15:07 -0800 Subject: [PATCH] fix: `generateDocs` gradle task failure - Changed the doc test to use mocked-up data instead of making actual calls to the end-point that does not exist anymore. [#182118433] Co-authored-by: Alicia Yingling --- .../uaa/provider/saml/idp/SamlTestUtils.java | 159 ++++++------- .../identity/uaa/login/TokenEndpointDocs.java | 212 ++++++++++-------- 2 files changed, 191 insertions(+), 180 deletions(-) diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/idp/SamlTestUtils.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/idp/SamlTestUtils.java index f4740772f3b..c2bc3ce3897 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/idp/SamlTestUtils.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/idp/SamlTestUtils.java @@ -286,43 +286,43 @@ public static SamlIdentityProviderDefinition createLocalSamlIdpDefinition(String return def; } -// @SuppressWarnings("unchecked") -// SAMLMessageContext mockSamlMessageContext() { -// return mockSamlMessageContext(mockAuthnRequest()); -// } + @SuppressWarnings("unchecked") + SAMLMessageContext mockSamlMessageContext() { + return mockSamlMessageContext(mockAuthnRequest()); + } + + @SuppressWarnings("unchecked") + SAMLMessageContext mockSamlMessageContext(AuthnRequest authnRequest) { + SAMLMessageContext context = new SAMLMessageContext(); -// @SuppressWarnings("unchecked") -// SAMLMessageContext mockSamlMessageContext(AuthnRequest authnRequest) { -// SAMLMessageContext context = new SAMLMessageContext(); -// // context.setLocalEntityId(IDP_ENTITY_ID); // context.setLocalEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); // EntityDescriptor idpMetadata = mockIdpMetadata(); // context.setLocalEntityMetadata(idpMetadata); // IDPSSODescriptor idpDescriptor = idpMetadata.getIDPSSODescriptor(SAML20P_NS); // context.setLocalEntityRoleMetadata(idpDescriptor); -// -// context.setPeerEntityId(SP_ENTITY_ID); -// context.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); -// EntityDescriptor spMetadata = mockSpMetadata(); -// context.setPeerEntityMetadata(spMetadata); -// SPSSODescriptor spDescriptor = spMetadata.getSPSSODescriptor(SAML20P_NS); -// context.setPeerEntityRoleMetadata(spDescriptor); -// context.setInboundSAMLMessage(authnRequest); -// -// SamlConfig config = new SamlConfig(); -// config.setPrivateKey(PROVIDER_PRIVATE_KEY); -// config.setPrivateKeyPassword(PROVIDER_PRIVATE_KEY_PASSWORD); -// config.setCertificate(PROVIDER_CERTIFICATE); -// KeyManager keyManager = new SamlKeyManagerFactory().getKeyManager(config); -// context.setLocalSigningCredential(keyManager.getDefaultCredential()); -// return context; -// } + + context.setPeerEntityId(SP_ENTITY_ID); + context.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); + EntityDescriptor spMetadata = mockSpMetadata(); + context.setPeerEntityMetadata(spMetadata); + SPSSODescriptor spDescriptor = spMetadata.getSPSSODescriptor(SAML20P_NS); + context.setPeerEntityRoleMetadata(spDescriptor); + context.setInboundSAMLMessage(authnRequest); + + SamlConfig config = new SamlConfig(); + config.setPrivateKey(PROVIDER_PRIVATE_KEY); + config.setPrivateKeyPassword(PROVIDER_PRIVATE_KEY_PASSWORD); + config.setCertificate(PROVIDER_CERTIFICATE); + KeyManager keyManager = new SamlKeyManagerFactory().getKeyManager(config); + context.setLocalSigningCredential(keyManager.getDefaultCredential()); + return context; + } // private EntityDescriptor mockIdpMetadata() { // return mockIdpMetadataGenerator().generateMetadata(); // } - +// // IdpMetadataGenerator mockIdpMetadataGenerator() { // IdpExtendedMetadata extendedMetadata = new IdpExtendedMetadata(); // @@ -356,48 +356,44 @@ private AuthnRequest mockAuthnRequest() { return mockAuthnRequest(null); } -// public Assertion mockAssertion( -// String issuerEntityId, -// String format, -// String username, -// String spEndpoint, -// String audienceEntityID, -// String privateKey, -// String keyPassword, -// String certificate) -// throws Exception { -// String authenticationId = UUID.randomUUID().toString(); -// Authentication authentication = mockUaaAuthentication(authenticationId); -// SAMLMessageContext context = mockSamlMessageContext(); -// IdpWebSsoProfileImpl profile = mockSsoWebProfileImpl(); -// IdpWebSSOProfileOptions options = new IdpWebSSOProfileOptions(); -// options.setAssertionsSigned(false); -// profile.buildResponse(authentication, context, options); -// Response response = (Response) context.getOutboundSAMLMessage(); -// Assertion assertion = response.getAssertions().get(0); -// DateTime until = new DateTime().plusHours(1); -// assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData().setRecipient(spEndpoint); -// assertion.getConditions().getAudienceRestrictions().get(0).getAudiences().get(0).setAudienceURI(audienceEntityID); -// assertion.getIssuer().setValue(issuerEntityId); -// assertion.getSubject().getNameID().setValue(username); -// assertion.getSubject().getNameID().setFormat(format); -// assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData().setInResponseTo(null); -// assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData().setNotOnOrAfter(until); -// assertion.getConditions().setNotOnOrAfter(until); -// SamlConfig config = new SamlConfig(); -// config.addAndActivateKey("active-key", new SamlKey(privateKey, keyPassword, certificate)); -// KeyManager keyManager = new SamlKeyManagerFactory().getKeyManager(config); -// SignatureBuilder signatureBuilder = (SignatureBuilder) builderFactory.getBuilder(Signature.DEFAULT_ELEMENT_NAME); -// Signature signature = signatureBuilder.buildObject(); -// final Credential defaultCredential = keyManager.getDefaultCredential(); -// signature.setSigningCredential(defaultCredential); -// SecurityHelper.prepareSignatureParams(signature, defaultCredential, null, null); -// assertion.setSignature(signature); -// Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(assertion); -// marshaller.marshall(assertion); -// Signer.signObject(signature); -// return assertion; -// } + public Assertion mockAssertion( + String issuerEntityId, + String format, + String username, + String spEndpoint, + String audienceEntityID, + String privateKey, + String keyPassword, + String certificate) + throws Exception { + String authenticationId = UUID.randomUUID().toString(); + Authentication authentication = mockUaaAuthentication(authenticationId); + SAMLMessageContext context = mockSamlMessageContext(); + Response response = (Response) context.getOutboundSAMLMessage(); + Assertion assertion = response.getAssertions().get(0); + DateTime until = new DateTime().plusHours(1); + assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData().setRecipient(spEndpoint); + assertion.getConditions().getAudienceRestrictions().get(0).getAudiences().get(0).setAudienceURI(audienceEntityID); + assertion.getIssuer().setValue(issuerEntityId); + assertion.getSubject().getNameID().setValue(username); + assertion.getSubject().getNameID().setFormat(format); + assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData().setInResponseTo(null); + assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData().setNotOnOrAfter(until); + assertion.getConditions().setNotOnOrAfter(until); + SamlConfig config = new SamlConfig(); + config.addAndActivateKey("active-key", new SamlKey(privateKey, keyPassword, certificate)); + KeyManager keyManager = new SamlKeyManagerFactory().getKeyManager(config); + SignatureBuilder signatureBuilder = (SignatureBuilder) builderFactory.getBuilder(Signature.DEFAULT_ELEMENT_NAME); + Signature signature = signatureBuilder.buildObject(); + final Credential defaultCredential = keyManager.getDefaultCredential(); + signature.setSigningCredential(defaultCredential); + SecurityHelper.prepareSignatureParams(signature, defaultCredential, null, null); + assertion.setSignature(signature); + Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(assertion); + marshaller.marshall(assertion); + Signer.signObject(signature); + return assertion; + } public String mockAssertionEncoded(Assertion assertion) throws Exception { AssertionMarshaller marshaller = new AssertionMarshaller(); @@ -406,9 +402,9 @@ public String mockAssertionEncoded(Assertion assertion) throws Exception { return Base64.encodeBase64URLSafeString(serializedElement.getBytes(StandardCharsets.UTF_8)); } -// public String mockAssertionEncoded(String issuerEntityID, String format, String username, String spEndpoint, String audienceEntityID) throws Exception { -// return mockAssertionEncoded(mockAssertion(issuerEntityID, format, username, spEndpoint, audienceEntityID, PROVIDER_PRIVATE_KEY, PROVIDER_PRIVATE_KEY_PASSWORD, PROVIDER_CERTIFICATE)); -// } + public String mockAssertionEncoded(String issuerEntityID, String format, String username, String spEndpoint, String audienceEntityID) throws Exception { + return mockAssertionEncoded(mockAssertion(issuerEntityID, format, username, spEndpoint, audienceEntityID, PROVIDER_PRIVATE_KEY, PROVIDER_PRIVATE_KEY_PASSWORD, PROVIDER_CERTIFICATE)); + } AuthnRequest mockAuthnRequest(String nameIDFormat) { @SuppressWarnings("unchecked") @@ -963,25 +959,4 @@ public static Document getMetadataDoc(String metadata) throws SAXException, IOEx InputSource is = new InputSource(new StringReader(metadata)); return documentBuilderFactory.newDocumentBuilder().parse(is); } - -// private static IdpWebSsoProfileImpl mockSsoWebProfileImpl() { -// IdpWebSsoProfileImpl profile = new IdpWebSsoProfileImpl(); -// JdbcScimUserProvisioning scimUserProvisioning = mock(JdbcScimUserProvisioning.class); -// profile.setScimUserProvisioning(scimUserProvisioning); -// JdbcSamlServiceProviderProvisioning samlServiceProviderProvisioning = mock(JdbcSamlServiceProviderProvisioning.class); -// profile.setSamlServiceProviderProvisioning(samlServiceProviderProvisioning); -// -// ScimUser user = new ScimUser(null, "johndoe", "John", "Doe"); -// -// SamlServiceProvider samlServiceProvider = new SamlServiceProvider(); -// SamlServiceProviderDefinition config = new SamlServiceProviderDefinition(); -// config.setAttributeMappings(new HashMap<>()); -// samlServiceProvider.setConfig(config); -// -// when(scimUserProvisioning.retrieve(anyString(), anyString())).thenReturn(user); -// when(samlServiceProviderProvisioning.retrieveByEntityId(any(), any())).thenReturn(samlServiceProvider); -// profile.setScimUserProvisioning(scimUserProvisioning); -// profile.setSamlServiceProviderProvisioning(samlServiceProviderProvisioning); -// return profile; -// } } diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/TokenEndpointDocs.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/TokenEndpointDocs.java index d8e325e7042..02679ac23b9 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/TokenEndpointDocs.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/TokenEndpointDocs.java @@ -439,94 +439,130 @@ void getTokenUsingUserTokenGrant() throws Exception { .andDo(document("{ClassName}/{methodName}", preprocessResponse(prettyPrint()), requestHeaders, requestParameters, responseFields)); } -// @Test -// void getTokenUsingSaml2BearerGrant() throws Exception { -// RandomValueStringGenerator generator = new RandomValueStringGenerator(); -// SamlTestUtils samlTestUtils = new SamlTestUtils(); -// samlTestUtils.initializeSimple(); -// -// String subdomain = generator.generate().toLowerCase(); -// //all our SAML defaults use :8080/uaa/ so we have to use that here too -// String host = subdomain + ".localhost"; -// String fullPath = "/uaa/oauth/token/alias/" + subdomain + ".cloudfoundry-saml-login"; -// String origin = subdomain + ".cloudfoundry-saml-login"; -// -// MockMvcUtils.IdentityZoneCreationResult zone = MockMvcUtils.createOtherIdentityZoneAndReturnResult(subdomain, mockMvc, this.webApplicationContext, null, IdentityZoneHolder.getCurrentZoneId()); -// -// //create an actual IDP, so we can fetch metadata -// String idpMetadata = MockMvcUtils.getIDPMetaData(mockMvc, subdomain); -// -// //create an IDP in the default zone -// SamlIdentityProviderDefinition idpDef = createLocalSamlIdpDefinition(origin, zone.getIdentityZone().getId(), idpMetadata); -// IdentityProvider provider = new IdentityProvider(); -// provider.setConfig(idpDef); -// provider.setActive(true); -// provider.setIdentityZoneId(zone.getIdentityZone().getId()); -// provider.setName(origin); -// provider.setOriginKey(origin); -// -// IdentityZoneHolder.set(zone.getIdentityZone()); -// identityProviderProvisioning.create(provider, zone.getIdentityZone().getId()); -// IdentityZoneHolder.clear(); -// -// String assertion = samlTestUtils.mockAssertionEncoded(subdomain + ".cloudfoundry-saml-login", -// "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", -// "Saml2BearerIntegrationUser", -// "http://" + subdomain + ".localhost:8080/uaa/oauth/token/alias/" + subdomain + ".cloudfoundry-saml-login", -// subdomain + ".cloudfoundry-saml-login" -// ); -// -// //create client in default zone -// String clientId = "testclient" + generator.generate(); -// setUpClients(clientId, "uaa.none", "uaa.user,openid", GRANT_TYPE_SAML2_BEARER + ",password,refresh_token", true, TEST_REDIRECT_URI, null, 600, zone.getIdentityZone()); -// -// -// //String fullPath = "/uaa/oauth/token"; -// MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(fullPath) -// .with(request -> { -// request.setServerPort(8080); -// request.setRequestURI(fullPath); -// request.setServerName(host); -// return request; -// }) -// .contextPath("/uaa") -// .accept(APPLICATION_JSON) -// .header(HOST, host) -// .contentType(APPLICATION_FORM_URLENCODED) -// .param("grant_type", TokenConstants.GRANT_TYPE_SAML2_BEARER) -// .param("client_id", clientId) -// .param("client_secret", "secret") -// .param("client_assertion", "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjU4ZDU1YzUwMGNjNmI1ODM3OTYxN2UwNmU3ZGVjNmNhIn0.eyJzdWIiOiJsb2dpbiIsImlzcyI6ImxvZ2luIiwianRpIjoiNThkNTVjNTAwY2M2YjU4Mzc5NjE3ZTA2ZTdhZmZlZSIsImV4cCI6MTIzNDU2NzgsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC91YWEvb2F1dGgvdG9rZW4ifQ.jwWw0OKZecd4ZjtwQ_ievqBVrh2SieqMF6vY74Oo5H6v-Ibcmumq96NLNtoUEwaAEQQOHb8MWcC8Gwi9dVQdCrtpomC86b_LKkihRBSKuqpw0udL9RMH5kgtC04ctsN0yZNifUWMP85VHn97Ual5eZ2miaBFob3H5jUe98CcBj1TSRehr64qBFYuwt9vD19q6U-ONhRt0RXBPB7ayHAOMYtb1LFIzGAiKvqWEy9f-TBPXSsETjKkAtSuM-WVWi4EhACMtSvI6iJN15f7qlverRSkGIdh1j2vPXpKKBJoRhoLw6YqbgcUC9vAr17wfa_POxaRHvh9JPty0ZXLA4XPtA") -// .param("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") -// .param("assertion", assertion) -// .param("scope", "openid"); -// -// final ParameterDescriptor assertionFormatParameter = parameterWithName("assertion").required().type(STRING).description("An XML based SAML 2.0 bearer assertion, which is Base64URl encoded."); -// Snippet requestParameters = requestParameters( -// clientIdParameter.description("The client ID of the receiving client, this client must have `urn:ietf:params:oauth:grant-type:saml2-bearer` grant type"), -// clientSecretParameter, -// clientAssertion, -// clientAssertionType, -// grantTypeParameter.description("The type of token grant requested, in this case `" + GRANT_TYPE_SAML2_BEARER + "`"), -// assertionFormatParameter, -// scopeParameter -// ); -// -// Snippet responseFields = responseFields( -// accessTokenFieldDescriptor, -// fieldWithPath("token_type").description("The type of the access token issued, always `bearer`"), -// fieldWithPath("expires_in").description("Number of seconds of lifetime for an access_token, when retrieved"), -// scopeFieldDescriptorWhenUserToken, -// refreshTokenFieldDescriptor, -// jtiFieldDescriptor -// ); -// -// mockMvc.perform(post) -// .andDo(document("{ClassName}/{methodName}", preprocessResponse(prettyPrint()), requestParameters, responseFields)) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.access_token").exists()) -// .andExpect(jsonPath("$.scope").value("openid")); -// } + @Test + void getTokenUsingSaml2BearerGrant() throws Exception { + SamlTestUtils samlTestUtils = new SamlTestUtils(); + samlTestUtils.initializeSimple(); + + String subdomain = "sds1ko"; + //all our SAML defaults use :8080/uaa/ so we have to use that here too + String host = subdomain + ".localhost"; + String fullPath = "/uaa/oauth/token/alias/" + subdomain + ".cloudfoundry-saml-login"; + String origin = subdomain + ".cloudfoundry-saml-login"; + + MockMvcUtils.IdentityZoneCreationResult zone = MockMvcUtils.createOtherIdentityZoneAndReturnResult(subdomain, mockMvc, this.webApplicationContext, null, IdentityZoneHolder.getCurrentZoneId()); + + //Mock an IDP metadata + String idpMetadata = "KuAftbgDBKaYcfFFu+PW7LfVzcs=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urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressurn:oasis:names:tc:SAML:2.0:nameid-format:persistenturn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"; + + //create an IDP in the default zone + SamlIdentityProviderDefinition idpDef = createLocalSamlIdpDefinition(origin, zone.getIdentityZone().getId(), idpMetadata); + IdentityProvider provider = new IdentityProvider(); + provider.setConfig(idpDef); + provider.setActive(true); + provider.setIdentityZoneId(zone.getIdentityZone().getId()); + provider.setName(origin); + provider.setOriginKey(origin); + + IdentityZoneHolder.set(zone.getIdentityZone()); + identityProviderProvisioning.create(provider, zone.getIdentityZone().getId()); + IdentityZoneHolder.clear(); + + String assertion = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDI6QXNzZXJ0aW9uIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0iYTRoNDQyMmk2aGY1MGQwNWI3Y2g1MmZoZWZoNmhoIiBJc3N1ZUluc3RhbnQ9IjIwMjMtMTItMTJUMTg6NTQ6NTIuMTI4WiIgVmVyc2lvbj0iMi4wIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPjxzYW1sMjpJc3N1ZXI-c2RzMWtvLmNsb3VkZm91bmRyeS1zYW1sLWxvZ2luPC9zYW1sMjpJc3N1ZXI-PGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI-PGRzOlNpZ25lZEluZm8-PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8-PGRzOlJlZmVyZW5jZSBVUkk9IiNhNGg0NDIyaTZoZjUwZDA1YjdjaDUyZmhlZmg2aGgiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiPjxlYzpJbmNsdXNpdmVOYW1lc3BhY2VzIHhtbG5zOmVjPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiIFByZWZpeExpc3Q9InhzIi8-PC9kczpUcmFuc2Zvcm0-PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT5FWVRZSitDMFBMMWtheGE5K2Z4YXVEdUZZd0E9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8-PGRzOlNpZ25hdHVyZVZhbHVlPklLMVoycWl6Q1pCT0JSS3F0bFQwb2JucDNoM1NRUk1kdTI3MUlUQytEa3c1RC9pRFFtbHVOZzc3SnFnWjc0NGFhY3JZNGQvVFJvMVl2dlQ5cm5PcGludmMzMGtjS0o5Y0IrOThWRXBkZjVRT2hNZEJyOVZjQllhWDVtWUdqZWNqZUlSNkZqWlY4eEI3Y0JCY2hrT2xzcmZlcnRwRS84S3JBeFJvV2hJSkxMTT08L2RzOlNpZ25hdHVyZVZhbHVlPjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSURTVENDQXJLZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRUUZBREI4TVFzd0NRWURWUVFHRXdKaGR6RU9NQXdHQTFVRUNCTUYKWVhKMVltRXhEakFNQmdOVkJBb1RCV0Z5ZFdKaE1RNHdEQVlEVlFRSEV3VmhjblZpWVRFT01Bd0dBMVVFQ3hNRllYSjFZbUV4RGpBTQpCZ05WQkFNVEJXRnlkV0poTVIwd0d3WUpLb1pJaHZjTkFRa0JGZzVoY25WaVlVQmhjblZpWVM1aGNqQWVGdzB4TlRFeE1qQXlNakkyCk1qZGFGdzB4TmpFeE1Ua3lNakkyTWpkYU1Id3hDekFKQmdOVkJBWVRBbUYzTVE0d0RBWURWUVFJRXdWaGNuVmlZVEVPTUF3R0ExVUUKQ2hNRllYSjFZbUV4RGpBTUJnTlZCQWNUQldGeWRXSmhNUTR3REFZRFZRUUxFd1ZoY25WaVlURU9NQXdHQTFVRUF4TUZZWEoxWW1FeApIVEFiQmdrcWhraUc5dzBCQ1FFV0RtRnlkV0poUUdGeWRXSmhMbUZ5TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCCmdRREh0QzVnVVh4QktwRXFaVExrTnZGd05Hbk5Ja2dnTk93T1FWTmJwTzBXVkhJaXZpZzVMMzlXcVM5dTBobkErTzdNQ0EvS2xyQVIKNGJYYWVWVmh3ZlVQWUJLSXBhYVRXRlFSNWNUUjFVRlpKTC9PRjl2QWZwT3d6bm9ENjZERENuUVZwYkNqdERZV1greDZpbXhuOEhDWQp4aE1vbDZablRiU3NGVzZWWmpGTWpRSURBUUFCbzRIYU1JSFhNQjBHQTFVZERnUVdCQlR4MGxEempIL2lPQm5PU1FhU0VXUUx4MXN5CkdEQ0Jwd1lEVlIwakJJR2ZNSUdjZ0JUeDBsRHpqSC9pT0JuT1NRYVNFV1FMeDFzeUdLR0JnS1IrTUh3eEN6QUpCZ05WQkFZVEFtRjMKTVE0d0RBWURWUVFJRXdWaGNuVmlZVEVPTUF3R0ExVUVDaE1GWVhKMVltRXhEakFNQmdOVkJBY1RCV0Z5ZFdKaE1RNHdEQVlEVlFRTApFd1ZoY25WaVlURU9NQXdHQTFVRUF4TUZZWEoxWW1FeEhUQWJCZ2txaGtpRzl3MEJDUUVXRG1GeWRXSmhRR0Z5ZFdKaExtRnlnZ0VBCk1Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRUJRQURnWUVBWXZCSjBIT1piYkhDbFhtR1VqR3MrR1MreEMxRk8vYW0KMnN1Q1NZcU5COWR5TVhmT1dpSjErVExKaytvL1ladDh2dXhDS2RjWllnbDRsL0w2UHhKOTgyU1JoYzgzWlcyZGtBWkk0TTAvVWQzbwplUGU4NGs4am0zQTdFdkg1d2k1aHZDa0tScHVSQnduM0VpK2pDUm91eFRiektQc3VDVkIrMXNOeXhNVFh6ZjA9PC9kczpYNTA5Q2VydGlmaWNhdGU-PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8-PC9kczpTaWduYXR1cmU-PHNhbWwyOlN1YmplY3Q-PHNhbWwyOk5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIj5TYW1sMkJlYXJlckludGVncmF0aW9uVXNlcjwvc2FtbDI6TmFtZUlEPjxzYW1sMjpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI-PHNhbWwyOlN1YmplY3RDb25maXJtYXRpb25EYXRhIE5vdE9uT3JBZnRlcj0iMjAyMy0xMi0xMlQxOTo1NDo1Mi4xNTlaIiBSZWNpcGllbnQ9Imh0dHA6Ly9zZHMxa28ubG9jYWxob3N0OjgwODAvdWFhL29hdXRoL3Rva2VuL2FsaWFzL3NkczFrby5jbG91ZGZvdW5kcnktc2FtbC1sb2dpbiIvPjwvc2FtbDI6U3ViamVjdENvbmZpcm1hdGlvbj48L3NhbWwyOlN1YmplY3Q-PHNhbWwyOkNvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDIzLTEyLTEyVDE4OjU0OjUyLjEzMloiIE5vdE9uT3JBZnRlcj0iMjAyMy0xMi0xMlQxOTo1NDo1Mi4xNTlaIj48c2FtbDI6QXVkaWVuY2VSZXN0cmljdGlvbj48c2FtbDI6QXVkaWVuY2U-c2RzMWtvLmNsb3VkZm91bmRyeS1zYW1sLWxvZ2luPC9zYW1sMjpBdWRpZW5jZT48L3NhbWwyOkF1ZGllbmNlUmVzdHJpY3Rpb24-PC9zYW1sMjpDb25kaXRpb25zPjxzYW1sMjpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMjMtMTItMTJUMTg6NTQ6NTIuMTI5WiIgU2Vzc2lvbkluZGV4PSJhNDU3NWUyNTBhN2Q1NWMyaGlmM2ZhYWlkaTA0aGEiPjxzYW1sMjpBdXRobkNvbnRleHQ-PHNhbWwyOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkPC9zYW1sMjpBdXRobkNvbnRleHRDbGFzc1JlZj48L3NhbWwyOkF1dGhuQ29udGV4dD48L3NhbWwyOkF1dGhuU3RhdGVtZW50PjxzYW1sMjpBdHRyaWJ1dGVTdGF0ZW1lbnQ-PHNhbWwyOkF0dHJpYnV0ZSBOYW1lPSJhdXRob3JpdGllcyI-PHNhbWwyOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnVhYS51c2VyPC9zYW1sMjpBdHRyaWJ1dGVWYWx1ZT48L3NhbWwyOkF0dHJpYnV0ZT48c2FtbDI6QXR0cmlidXRlIE5hbWU9ImVtYWlsIj48c2FtbDI6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI-bWFyaXNzYUB0ZXN0aW5nLm9yZzwvc2FtbDI6QXR0cmlidXRlVmFsdWU-PC9zYW1sMjpBdHRyaWJ1dGU-PHNhbWwyOkF0dHJpYnV0ZSBOYW1lPSJpZCI-PHNhbWwyOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPjFmODU5NzVhLTRhYWUtNGEyZS1hOWFhLWYyNmMyZjAwMzBlNDwvc2FtbDI6QXR0cmlidXRlVmFsdWU-PC9zYW1sMjpBdHRyaWJ1dGU-PHNhbWwyOkF0dHJpYnV0ZSBOYW1lPSJuYW1lIj48c2FtbDI6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI-bWFyaXNzYTwvc2FtbDI6QXR0cmlidXRlVmFsdWU-PC9zYW1sMjpBdHRyaWJ1dGU-PHNhbWwyOkF0dHJpYnV0ZSBOYW1lPSJvcmlnaW4iPjxzYW1sMjpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj51YWE8L3NhbWwyOkF0dHJpYnV0ZVZhbHVlPjwvc2FtbDI6QXR0cmlidXRlPjxzYW1sMjpBdHRyaWJ1dGUgTmFtZT0iem9uZUlkIj48c2FtbDI6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI-dWFhPC9zYW1sMjpBdHRyaWJ1dGVWYWx1ZT48L3NhbWwyOkF0dHJpYnV0ZT48L3NhbWwyOkF0dHJpYnV0ZVN0YXRlbWVudD48L3NhbWwyOkFzc2VydGlvbj4"; + + //create client in default zone + String clientId = "testclient" + generator.generate(); + setUpClients(clientId, "uaa.none", "uaa.user,openid", GRANT_TYPE_SAML2_BEARER + ",password,refresh_token", true, TEST_REDIRECT_URI, null, 600, zone.getIdentityZone()); + + + //String fullPath = "/uaa/oauth/token"; + MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(fullPath) + .with(request -> { + request.setServerPort(8080); + request.setRequestURI(fullPath); + request.setServerName(host); + return request; + }) + .contextPath("/uaa") + .accept(APPLICATION_JSON) + .header(HOST, host) + .contentType(APPLICATION_FORM_URLENCODED) + .param("grant_type", TokenConstants.GRANT_TYPE_SAML2_BEARER) + .param("client_id", clientId) + .param("client_secret", "secret") + .param("client_assertion", "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjU4ZDU1YzUwMGNjNmI1ODM3OTYxN2UwNmU3ZGVjNmNhIn0.eyJzdWIiOiJsb2dpbiIsImlzcyI6ImxvZ2luIiwianRpIjoiNThkNTVjNTAwY2M2YjU4Mzc5NjE3ZTA2ZTdhZmZlZSIsImV4cCI6MTIzNDU2NzgsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC91YWEvb2F1dGgvdG9rZW4ifQ.jwWw0OKZecd4ZjtwQ_ievqBVrh2SieqMF6vY74Oo5H6v-Ibcmumq96NLNtoUEwaAEQQOHb8MWcC8Gwi9dVQdCrtpomC86b_LKkihRBSKuqpw0udL9RMH5kgtC04ctsN0yZNifUWMP85VHn97Ual5eZ2miaBFob3H5jUe98CcBj1TSRehr64qBFYuwt9vD19q6U-ONhRt0RXBPB7ayHAOMYtb1LFIzGAiKvqWEy9f-TBPXSsETjKkAtSuM-WVWi4EhACMtSvI6iJN15f7qlverRSkGIdh1j2vPXpKKBJoRhoLw6YqbgcUC9vAr17wfa_POxaRHvh9JPty0ZXLA4XPtA") + .param("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") + .param("assertion", assertion) + .param("scope", "openid"); + + final ParameterDescriptor assertionFormatParameter = parameterWithName("assertion").required().type(STRING).description("An XML based SAML 2.0 bearer assertion, which is Base64URl encoded."); + Snippet requestParameters = requestParameters( + clientIdParameter.description("The client ID of the receiving client, this client must have `urn:ietf:params:oauth:grant-type:saml2-bearer` grant type"), + clientSecretParameter, + clientAssertion, + clientAssertionType, + grantTypeParameter.description("The type of token grant requested, in this case `" + GRANT_TYPE_SAML2_BEARER + "`"), + assertionFormatParameter, + scopeParameter + ); + + Snippet responseFields = responseFields( + accessTokenFieldDescriptor, + fieldWithPath("token_type").description("The type of the access token issued, always `bearer`"), + fieldWithPath("expires_in").description("Number of seconds of lifetime for an access_token, when retrieved"), + scopeFieldDescriptorWhenUserToken, + refreshTokenFieldDescriptor, + jtiFieldDescriptor + ); + + mockMvc.perform(post) + .andDo(document("{ClassName}/{methodName}", preprocessResponse(prettyPrint()), requestParameters, responseFields)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.access_token").exists()) + .andExpect(jsonPath("$.scope").value("openid")); + } @Test void getTokenWithClientAuthInHeader() throws Exception {