Skip to content

Commit

Permalink
Fix documentation of new field
Browse files Browse the repository at this point in the history
Add OIDC custom attribute map
  • Loading branch information
fhanik committed Dec 16, 2016
1 parent 51f538f commit 7a3f09f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
Expand Up @@ -14,6 +14,7 @@


import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.cloudfoundry.identity.uaa.ServerRunning; import org.cloudfoundry.identity.uaa.ServerRunning;
import org.cloudfoundry.identity.uaa.account.UserInfoResponse;
import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.constants.OriginKeys;
import org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils; import org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils;
import org.cloudfoundry.identity.uaa.integration.util.ScreenshotOnFail; import org.cloudfoundry.identity.uaa.integration.util.ScreenshotOnFail;
Expand Down Expand Up @@ -41,21 +42,26 @@
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.jwt.Jwt; import org.springframework.security.jwt.Jwt;
import org.springframework.security.oauth2.client.test.TestAccounts; import org.springframework.security.oauth2.client.test.TestAccounts;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestOperations;


import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;


import static org.cloudfoundry.identity.uaa.constants.OriginKeys.OIDC10; import static org.cloudfoundry.identity.uaa.constants.OriginKeys.OIDC10;
import static org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils.getZoneAdminToken; import static org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils.getZoneAdminToken;
import static org.cloudfoundry.identity.uaa.oauth.token.ClaimConstants.USER_ATTRIBUTES;
import static org.cloudfoundry.identity.uaa.provider.ExternalIdentityProviderDefinition.USER_NAME_ATTRIBUTE_NAME; import static org.cloudfoundry.identity.uaa.provider.ExternalIdentityProviderDefinition.USER_NAME_ATTRIBUTE_NAME;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;


Expand Down Expand Up @@ -173,7 +179,7 @@ public void successfulLoginWithOIDC_and_SAML_Provider() throws Exception {
This test creates an OIDC provider. That provider in turn has a SAML provider. This test creates an OIDC provider. That provider in turn has a SAML provider.
The end user is authenticated using The end user is authenticated using
*/ */
createOIDCProviderWithRequestedScopes(); String clientId = createOIDCProviderWithRequestedScopes();
webDriver.get(baseUrl + "/login"); webDriver.get(baseUrl + "/login");
webDriver.findElement(By.linkText("My OIDC Provider")).click(); webDriver.findElement(By.linkText("My OIDC Provider")).click();
Assert.assertThat(webDriver.getCurrentUrl(), Matchers.containsString("oidc10.identity.cf-app.com")); Assert.assertThat(webDriver.getCurrentUrl(), Matchers.containsString("oidc10.identity.cf-app.com"));
Expand All @@ -190,10 +196,11 @@ public void successfulLoginWithOIDC_and_SAML_Provider() throws Exception {


Cookie cookie= webDriver.manage().getCookieNamed("JSESSIONID"); Cookie cookie= webDriver.manage().getCookieNamed("JSESSIONID");
System.out.println("cookie = " + String.format("%s=%s",cookie.getName(), cookie.getValue())); System.out.println("cookie = " + String.format("%s=%s",cookie.getName(), cookie.getValue()));

Map<String,String> authCodeTokenResponse = IntegrationTestUtils.getAuthorizationCodeTokenMap(serverRunning, Map<String,String> authCodeTokenResponse = IntegrationTestUtils.getAuthorizationCodeTokenMap(serverRunning,
UaaTestAccounts.standard(serverRunning), UaaTestAccounts.standard(serverRunning),
"login", clientId,
"loginsecret", "secret",
null, null,
null, null,
"token id_token", "token id_token",
Expand All @@ -212,6 +219,14 @@ public void successfulLoginWithOIDC_and_SAML_Provider() throws Exception {
Map<String,Object> acr = (Map<String, Object>) claims.get(ClaimConstants.ACR); Map<String,Object> acr = (Map<String, Object>) claims.get(ClaimConstants.ACR);
assertNotNull("acr claim should contain values attribute", acr.get("values")); assertNotNull("acr claim should contain values attribute", acr.get("values"));
assertThat((List<String>) acr.get("values"), containsInAnyOrder(AuthnContext.PASSWORD_AUTHN_CTX)); assertThat((List<String>) acr.get("values"), containsInAnyOrder(AuthnContext.PASSWORD_AUTHN_CTX));

UserInfoResponse userInfo = IntegrationTestUtils.getUserInfo(baseUrl, authCodeTokenResponse.get("access_token"));

Map<String,List<String>> userAttributeMap = (Map<String,List<String>>) userInfo.getAttributeValue(USER_ATTRIBUTES);
assertNotNull(userAttributeMap);
List<String> clientIds = userAttributeMap.get("the_client_id");
assertNotNull(clientIds);
assertEquals("identity", clientIds.get(0));
} }


@Test @Test
Expand Down Expand Up @@ -297,18 +312,20 @@ private IdentityProvider<OIDCIdentityProviderDefinition> createAzureProvider() t
return result; return result;
} }


private void createOIDCProviderWithRequestedScopes() throws Exception { private String createOIDCProviderWithRequestedScopes() throws Exception {
createOIDCProviderWithRequestedScopes(null, "https://oidc10.identity.cf-app.com"); return createOIDCProviderWithRequestedScopes(null, "https://oidc10.identity.cf-app.com");
} }
private void createOIDCProviderWithRequestedScopes(String issuer, final String urlBase) throws Exception { private String createOIDCProviderWithRequestedScopes(String issuer, final String urlBase) throws Exception {
createOIDCProviderWithRequestedScopes(issuer, urlBase, null); return createOIDCProviderWithRequestedScopes(issuer, urlBase, null);
} }
private void createOIDCProviderWithRequestedScopes(String issuer, String urlBase, String keyUrl) throws Exception { private String createOIDCProviderWithRequestedScopes(String issuer, String urlBase, String keyUrl) throws Exception {
IdentityProvider<AbstractXOAuthIdentityProviderDefinition> identityProvider = new IdentityProvider<>(); IdentityProvider<AbstractXOAuthIdentityProviderDefinition> identityProvider = new IdentityProvider<>();
identityProvider.setName("my oidc provider"); identityProvider.setName("my oidc provider");
identityProvider.setIdentityZoneId(OriginKeys.UAA); identityProvider.setIdentityZoneId(OriginKeys.UAA);
OIDCIdentityProviderDefinition config = new OIDCIdentityProviderDefinition(); OIDCIdentityProviderDefinition config = new OIDCIdentityProviderDefinition();
config.addAttributeMapping(USER_NAME_ATTRIBUTE_NAME, "user_name"); config.addAttributeMapping(USER_NAME_ATTRIBUTE_NAME, "user_name");
config.addAttributeMapping("user.attribute." + "the_client_id", "cid");
config.setStoreCustomAttributes(true);
config.setAuthUrl(new URL(urlBase + "/oauth/authorize")); config.setAuthUrl(new URL(urlBase + "/oauth/authorize"));
config.setTokenUrl(new URL(urlBase + "/oauth/token")); config.setTokenUrl(new URL(urlBase + "/oauth/token"));
config.setTokenKeyUrl(keyUrl==null ? new URL(urlBase + "/token_key") : new URL(keyUrl)); config.setTokenKeyUrl(keyUrl==null ? new URL(urlBase + "/token_key") : new URL(keyUrl));
Expand All @@ -327,5 +344,13 @@ private void createOIDCProviderWithRequestedScopes(String issuer, String urlBase
String clientCredentialsToken = IntegrationTestUtils.getClientCredentialsToken(baseUrl, "admin", "adminsecret"); String clientCredentialsToken = IntegrationTestUtils.getClientCredentialsToken(baseUrl, "admin", "adminsecret");
IntegrationTestUtils.createOrUpdateProvider(clientCredentialsToken, baseUrl, identityProvider); IntegrationTestUtils.createOrUpdateProvider(clientCredentialsToken, baseUrl, identityProvider);
originKey = "puppy"; originKey = "puppy";

BaseClientDetails clientDetails = new BaseClientDetails(new RandomValueStringGenerator().generate(), null, "openid,user_attributes", "authorization_code,client_credentials", "uaa.admin,scim.read,scim.write,uaa.resource");
clientDetails.setClientSecret("secret");
clientDetails.setAutoApproveScopes(Collections.singleton("true"));
clientDetails = IntegrationTestUtils.createClientAsZoneAdmin(clientCredentialsToken, baseUrl, null, clientDetails);
clientDetails.setClientSecret("secret");
return clientDetails.getClientId();

} }
} }
Expand Up @@ -98,6 +98,7 @@ public class IdentityProviderEndpointsDocs extends InjectedMockContextTest {
private static final String PHONE_NUMBER_DESC = "Map `phone_number` to the attribute for phone number in the provider assertion."; private static final String PHONE_NUMBER_DESC = "Map `phone_number` to the attribute for phone number in the provider assertion.";
private static final String GIVEN_NAME_DESC = "Map `given_name` to the attribute for given name in the provider assertion."; private static final String GIVEN_NAME_DESC = "Map `given_name` to the attribute for given name in the provider assertion.";


private static final FieldDescriptor STORE_CUSTOM_ATTRIBUTES = fieldWithPath("config.storeCustomAttributes").optional(false).type(BOOLEAN).description("Set to true, to store custom user attributes to be fetched from the /userinfo endpoint");
private static final FieldDescriptor SKIP_SSL_VALIDATION = fieldWithPath("config.skipSslValidation").optional(false).type(BOOLEAN).description("Set to true, to skip SSL validation when fetching metadata."); private static final FieldDescriptor SKIP_SSL_VALIDATION = fieldWithPath("config.skipSslValidation").optional(false).type(BOOLEAN).description("Set to true, to skip SSL validation when fetching metadata.");
private static final FieldDescriptor ATTRIBUTE_MAPPING = fieldWithPath("config.attributeMappings").optional(null).type(STRING).description("Map external attribute to UAA recognized mappings."); private static final FieldDescriptor ATTRIBUTE_MAPPING = fieldWithPath("config.attributeMappings").optional(null).type(STRING).description("Map external attribute to UAA recognized mappings.");
private static final FieldDescriptor ADD_SHADOW_USER = fieldWithPath("config.addShadowUserOnLogin").optional(true).description("Whether users should be allowed to authenticate from LDAP without having a user pre-populated in the users database"); private static final FieldDescriptor ADD_SHADOW_USER = fieldWithPath("config.addShadowUserOnLogin").optional(true).description("Whether users should be allowed to authenticate from LDAP without having a user pre-populated in the users database");
Expand Down Expand Up @@ -130,7 +131,8 @@ public class IdentityProviderEndpointsDocs extends InjectedMockContextTest {
PROVIDER_DESC, PROVIDER_DESC,
EMAIL_DOMAIN, EMAIL_DOMAIN,
ACTIVE, ACTIVE,
ADD_SHADOW_USER ADD_SHADOW_USER,
STORE_CUSTOM_ATTRIBUTES
}; };


private static ApacheDsSSLContainer apacheDS; private static ApacheDsSSLContainer apacheDS;
Expand Down Expand Up @@ -348,6 +350,7 @@ public void createSAMLIdentityProvider() throws Exception {
fieldWithPath("type").required().description("`saml`"), fieldWithPath("type").required().description("`saml`"),
fieldWithPath("originKey").required().description("A unique alias for the SAML provider"), fieldWithPath("originKey").required().description("A unique alias for the SAML provider"),
SKIP_SSL_VALIDATION, SKIP_SSL_VALIDATION,
STORE_CUSTOM_ATTRIBUTES,
fieldWithPath("config.metaDataLocation").required().type(STRING).description("SAML Metadata - either an XML string or a URL that will deliver XML content"), fieldWithPath("config.metaDataLocation").required().type(STRING).description("SAML Metadata - either an XML string or a URL that will deliver XML content"),
fieldWithPath("config.nameID").optional(null).type(STRING).description("The name ID to use for the username, default is \"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\"."), fieldWithPath("config.nameID").optional(null).type(STRING).description("The name ID to use for the username, default is \"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\"."),
fieldWithPath("config.assertionConsumerIndex").optional(null).type(NUMBER).description("SAML assertion consumer index, default is 0"), fieldWithPath("config.assertionConsumerIndex").optional(null).type(NUMBER).description("SAML assertion consumer index, default is 0"),
Expand Down

0 comments on commit 7a3f09f

Please sign in to comment.