/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.admin;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
import org.junit.Test;
import org.keycloak.admin.client.resource.IdentityProviderResource;
import org.keycloak.dom.saml.v2.metadata.EndpointType;
import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
import org.keycloak.dom.saml.v2.metadata.IndexedEndpointType;
import org.keycloak.dom.saml.v2.metadata.KeyTypes;
import org.keycloak.dom.saml.v2.metadata.SPSSODescriptorType;
import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.utils.StripSecretsUtils;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.saml.common.exceptions.ParsingException;
import org.keycloak.saml.common.util.StaxParserUtil;
import org.keycloak.saml.processing.core.parsers.saml.metadata.SAMLEntityDescriptorParser;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.util.AdminEventPaths;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.crypto.dsig.XMLSignature;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.hamcrest.Matchers.*;
import org.keycloak.dom.saml.v2.metadata.KeyDescriptorType;
import org.w3c.dom.NodeList;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class IdentityProviderTest extends AbstractAdminTest {
// Certificate imported from
private static final String SIGNING_CERT_1 = "MIICmzCCAYMCBgFUYnC0OjANBgkqhkiG9w0BAQsFADARMQ8wDQY"
+ "DVQQDDAZtYXN0ZXIwHhcNMTYwNDI5MTQzMjEzWhcNMjYwNDI5MTQzMzUzWjARMQ8wDQYDVQQDDAZtYXN0ZXI"
+ "wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCN25AW1poMEZRbuMAHG58AThZmCwMV6/Gcui4mjGa"
+ "cRFyudgqzLjQ2rxpoW41JAtLjbjeAhuWvirUcFVcOeS3gM/ZC27qCpYighAcylZz6MYocnEe1+e8rPPk4JlI"
+ "D6Wv62dgu+pL/vYsQpRhvD3Y2c/ytgr5D32xF+KnzDehUy5BSyzypvu12Wq9mS5vK5tzkN37EjkhpY2ZxaXP"
+ "ubjDIITCAL4Q8M/m5IlacBaUZbzI4AQrHnMP1O1IH2dHSWuMiBe+xSDTco72PmuYPJKTV4wQdeBUIkYbfLc4"
+ "RxVmXEvgkQgyW86EoMPxlWJpj7+mTIR+l+2thZPr/VgwTs82rAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAA/"
+ "Ip/Hi8RoVu5ouaFFlc5whT7ltuK8slfLGW4tM4vJXhInYwsqIRQKBNDYW/64xle3eII4u1yAH1OYRRwEs7Em"
+ "1pr4QuFuTY1at+aE0sE46XDlyESI0txJjWxYoT133vM0We2pj1b2nxgU30rwjKA3whnKEfTEYT/n3JBSqNgg"
+ "y6l8ZGw/oPSgvPaR4+xeB1tfQFC4VrLoYKoqH6hAL530nKxL+qV8AIfL64NDEE8ankIAEDAAFe8x3CPUfXR/"
+ "p4KOANKkpz8ieQaHDb1eITkAwUwjESj6UF9D1aePlhWls/HX0gujFXtWfWfrJ8CU/ogwlH8y1jgRuLjFQYZk6llc=";
private static final String SIGNING_CERT_2 = "MIIBnDCCAQUCBgFYKXKsPTANBgkqhkiG9w0BAQsFADAUMRIwEAY"
+ "DVQQDDAlzYW1sLWRlbW8wHhcNMTYxMTAzMDkwNzEwWhcNMjYxMTAzMDkwODUwWjAUMRIwEAYDVQQDDAlzYW1"
+ "sLWRlbW8wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKtWsK5O0CtuBpnMvWG+HTG0vmZzujQ2o9WdheQ"
+ "u+BzCILcGMsbDW0YQaglpcO5JpGWWhubnckGGPHfdQ2/7nP9QwbiTK0FbGF41UqcvoaCqU1psxoV88s8IXyQ"
+ "CAqeyLv00yj6foqdJjxh5SZ5z+na+M7Y2OxIBVxYRAxWEnfUvAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAhet"
+ "vOU8TyqfZF5jpv0IcrviLl/DoFrbjByeHR+pu/vClcAOjL/u7oQELuuTfNsBI4tpexUj5G8q/YbEz0gk7idf"
+ "LXrAUVcsR73oTngrhRfwUSmPrjjK0kjcRb6HL9V/+wh3R/6mEd59U08ExT8N38rhmn0CI3ehMdebReprP7U8=";
@Test
public void testFindAll() {
create(createRep("google", "google"));
create(createRep("facebook", "facebook"));
Assert.assertNames(realm.identityProviders().findAll(), "google", "facebook");
}
@Test
public void testCreate() {
IdentityProviderRepresentation newIdentityProvider = createRep("new-identity-provider", "oidc");
newIdentityProvider.getConfig().put("clientId", "clientId");
newIdentityProvider.getConfig().put("clientSecret", "some secret value");
create(newIdentityProvider);
IdentityProviderResource identityProviderResource = realm.identityProviders().get("new-identity-provider");
assertNotNull(identityProviderResource);
IdentityProviderRepresentation representation = identityProviderResource.toRepresentation();
assertNotNull(representation);
assertNotNull(representation.getInternalId());
assertEquals("new-identity-provider", representation.getAlias());
assertEquals("oidc", representation.getProviderId());
assertEquals("clientId", representation.getConfig().get("clientId"));
assertEquals(ComponentRepresentation.SECRET_VALUE, representation.getConfig().get("clientSecret"));
assertTrue(representation.isEnabled());
assertFalse(representation.isStoreToken());
assertFalse(representation.isTrustEmail());
assertEquals("some secret value", testingClient.testing("admin-client-test").getIdentityProviderConfig("new-identity-provider").get("clientSecret"));
IdentityProviderRepresentation rep = realm.identityProviders().findAll().stream().filter(i -> i.getAlias().equals("new-identity-provider")).findFirst().get();
assertEquals(ComponentRepresentation.SECRET_VALUE, rep.getConfig().get("clientSecret"));
}
@Test
public void testUpdate() {
IdentityProviderRepresentation newIdentityProvider = createRep("update-identity-provider", "oidc");
newIdentityProvider.getConfig().put("clientId", "clientId");
newIdentityProvider.getConfig().put("clientSecret", "some secret value");
create(newIdentityProvider);
IdentityProviderResource identityProviderResource = realm.identityProviders().get("update-identity-provider");
assertNotNull(identityProviderResource);
IdentityProviderRepresentation representation = identityProviderResource.toRepresentation();
assertNotNull(representation);
assertEquals("update-identity-provider", representation.getAlias());
representation.setAlias("changed-alias");
representation.setEnabled(false);
representation.setStoreToken(true);
representation.getConfig().put("clientId", "changedClientId");
identityProviderResource.update(representation);
AdminEventRepresentation event = assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.identityProviderPath("update-identity-provider"), representation, ResourceType.IDENTITY_PROVIDER);
assertFalse(event.getRepresentation().contains("some secret value"));
assertTrue(event.getRepresentation().contains(ComponentRepresentation.SECRET_VALUE));
identityProviderResource = realm.identityProviders().get(representation.getInternalId());
assertNotNull(identityProviderResource);
representation = identityProviderResource.toRepresentation();
assertFalse(representation.isEnabled());
assertTrue(representation.isStoreToken());
assertEquals("changedClientId", representation.getConfig().get("clientId"));
assertEquals("some secret value", testingClient.testing("admin-client-test").getIdentityProviderConfig("changed-alias").get("clientSecret"));
}
@Test
public void testRemove() {
IdentityProviderRepresentation newIdentityProvider = createRep("remove-identity-provider", "saml");
create(newIdentityProvider);
IdentityProviderResource identityProviderResource = realm.identityProviders().get("remove-identity-provider");
assertNotNull(identityProviderResource);
IdentityProviderRepresentation representation = identityProviderResource.toRepresentation();
assertNotNull(representation);
identityProviderResource.remove();
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.identityProviderPath("remove-identity-provider"), ResourceType.IDENTITY_PROVIDER);
try {
realm.identityProviders().get("remove-identity-provider").toRepresentation();
Assert.fail("Not expected to found");
} catch (NotFoundException nfe) {
// Expected
}
}
private void create(IdentityProviderRepresentation idpRep) {
Response response = realm.identityProviders().create(idpRep);
Assert.assertNotNull(ApiUtil.getCreatedId(response));
response.close();
getCleanup().addIdentityProviderAlias(idpRep.getAlias());
String secret = idpRep.getConfig() != null ? idpRep.getConfig().get("clientSecret") : null;
idpRep = StripSecretsUtils.strip(idpRep);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderPath(idpRep.getAlias()), idpRep, ResourceType.IDENTITY_PROVIDER);
if (secret != null) {
idpRep.getConfig().put("clientSecret", secret);
}
}
private IdentityProviderRepresentation createRep(String id, String providerId) {
return createRep(id, providerId, null);
}
private IdentityProviderRepresentation createRep(String id, String providerId, Map<String, String> config) {
IdentityProviderRepresentation idp = new IdentityProviderRepresentation();
idp.setAlias(id);
idp.setDisplayName(id);
idp.setProviderId(providerId);
idp.setEnabled(true);
if (config != null) {
idp.setConfig(config);
}
return idp;
}
@Test
public void testMapperTypes() {
IdentityProviderResource provider;
Map<String, IdentityProviderMapperTypeRepresentation> mapperTypes;
create(createRep("google", "google"));
provider = realm.identityProviders().get("google");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "google-user-attribute-mapper");
create(createRep("facebook", "facebook"));
provider = realm.identityProviders().get("facebook");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "facebook-user-attribute-mapper");
create(createRep("github", "github"));
provider = realm.identityProviders().get("github");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "github-user-attribute-mapper");
create(createRep("twitter", "twitter"));
provider = realm.identityProviders().get("twitter");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes);
create(createRep("linkedin", "linkedin"));
provider = realm.identityProviders().get("linkedin");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "linkedin-user-attribute-mapper");
create(createRep("microsoft", "microsoft"));
provider = realm.identityProviders().get("microsoft");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "microsoft-user-attribute-mapper");
create(createRep("stackoverflow", "stackoverflow"));
provider = realm.identityProviders().get("stackoverflow");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "stackoverflow-user-attribute-mapper");
create(createRep("keycloak-oidc", "keycloak-oidc"));
provider = realm.identityProviders().get("keycloak-oidc");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "keycloak-oidc-role-to-role-idp-mapper", "oidc-user-attribute-idp-mapper", "oidc-role-idp-mapper", "oidc-username-idp-mapper");
create(createRep("oidc", "oidc"));
provider = realm.identityProviders().get("oidc");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "oidc-user-attribute-idp-mapper", "oidc-role-idp-mapper", "oidc-username-idp-mapper");
create(createRep("saml", "saml"));
provider = realm.identityProviders().get("saml");
mapperTypes = provider.getMapperTypes();
assertMapperTypes(mapperTypes, "saml-user-attribute-idp-mapper", "saml-role-idp-mapper", "saml-username-idp-mapper");
}
private void assertMapperTypes(Map<String, IdentityProviderMapperTypeRepresentation> mapperTypes, String ... mapperIds) {
Set<String> expected = new HashSet<>();
expected.add("hardcoded-user-session-attribute-idp-mapper");
expected.add("oidc-hardcoded-role-idp-mapper");
expected.add("hardcoded-attribute-idp-mapper");
for (String id: mapperIds) {
expected.add(id);
}
Assert.assertEquals("mapperTypes", expected, mapperTypes.keySet());
}
@Test
public void testNoExport() {
create(createRep("keycloak-oidc", "keycloak-oidc"));
Response response = realm.identityProviders().get("keycloak-oidc").export("json");
Assert.assertEquals("status", 204, response.getStatus());
String body = response.readEntity(String.class);
Assert.assertNull("body", body);
response.close();
}
@Test
public void testSamlImportAndExport() throws URISyntaxException, IOException, ParsingException {
// Use import-config to convert IDPSSODescriptor file into key value pairs
// to use when creating a SAML Identity Provider
MultipartFormDataOutput form = new MultipartFormDataOutput();
form.addFormData("providerId", "saml", MediaType.TEXT_PLAIN_TYPE);
URL idpMeta = getClass().getClassLoader().getResource("admin-test/saml-idp-metadata.xml");
byte [] content = Files.readAllBytes(Paths.get(idpMeta.toURI()));
String body = new String(content, Charset.forName("utf-8"));
form.addFormData("file", body, MediaType.APPLICATION_XML_TYPE, "saml-idp-metadata.xml");
Map<String, String> result = realm.identityProviders().importFrom(form);
assertSamlImport(result, SIGNING_CERT_1);
// Create new SAML identity provider using configuration retrieved from import-config
create(createRep("saml", "saml", result));
IdentityProviderResource provider = realm.identityProviders().get("saml");
IdentityProviderRepresentation rep = provider.toRepresentation();
assertCreatedSamlIdp(rep);
// Now list the providers - we should see the one just created
List<IdentityProviderRepresentation> providers = realm.identityProviders().findAll();
Assert.assertNotNull("identityProviders not null", providers);
Assert.assertEquals("identityProviders instance count", 1, providers.size());
assertEqual(rep, providers.get(0));
// Perform export, and make sure some of the values are like they're supposed to be
Response response = realm.identityProviders().get("saml").export("xml");
Assert.assertEquals(200, response.getStatus());
body = response.readEntity(String.class);
response.close();
assertSamlExport(body);
}
@Test
public void testSamlImportAndExportMultipleSigningKeys() throws URISyntaxException, IOException, ParsingException {
// Use import-config to convert IDPSSODescriptor file into key value pairs
// to use when creating a SAML Identity Provider
MultipartFormDataOutput form = new MultipartFormDataOutput();
form.addFormData("providerId", "saml", MediaType.TEXT_PLAIN_TYPE);
URL idpMeta = getClass().getClassLoader().getResource("admin-test/saml-idp-metadata-two-signing-certs.xml");
byte [] content = Files.readAllBytes(Paths.get(idpMeta.toURI()));
String body = new String(content, Charset.forName("utf-8"));
form.addFormData("file", body, MediaType.APPLICATION_XML_TYPE, "saml-idp-metadata-two-signing-certs");
Map<String, String> result = realm.identityProviders().importFrom(form);
assertSamlImport(result, SIGNING_CERT_1 + "," + SIGNING_CERT_2);
// Create new SAML identity provider using configuration retrieved from import-config
create(createRep("saml", "saml", result));
IdentityProviderResource provider = realm.identityProviders().get("saml");
IdentityProviderRepresentation rep = provider.toRepresentation();
assertCreatedSamlIdp(rep);
// Now list the providers - we should see the one just created
List<IdentityProviderRepresentation> providers = realm.identityProviders().findAll();
Assert.assertNotNull("identityProviders not null", providers);
Assert.assertEquals("identityProviders instance count", 1, providers.size());
assertEqual(rep, providers.get(0));
// Perform export, and make sure some of the values are like they're supposed to be
Response response = realm.identityProviders().get("saml").export("xml");
Assert.assertEquals(200, response.getStatus());
body = response.readEntity(String.class);
response.close();
assertSamlExport(body);
}
@Test
public void testMappers() {
create(createRep("google", "google"));
IdentityProviderResource provider = realm.identityProviders().get("google");
IdentityProviderMapperRepresentation mapper = new IdentityProviderMapperRepresentation();
mapper.setIdentityProviderAlias("google");
mapper.setName("my_mapper");
mapper.setIdentityProviderMapper("oidc-hardcoded-role-idp-mapper");
Map<String, String> config = new HashMap<>();
config.put("role", "offline_access");
mapper.setConfig(config);
// createRep and add mapper
Response response = provider.addMapper(mapper);
String id = ApiUtil.getCreatedId(response);
Assert.assertNotNull(id);
response.close();
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderMapperPath("google", id), mapper, ResourceType.IDENTITY_PROVIDER_MAPPER);
// list mappers
List<IdentityProviderMapperRepresentation> mappers = provider.getMappers();
Assert.assertEquals("mappers count", 1, mappers.size());
Assert.assertEquals("newly created mapper id", id, mappers.get(0).getId());
// get mapper
mapper = provider.getMapperById(id);
Assert.assertNotNull("mapperById not null", mapper);
Assert.assertEquals("mapper id", id, mapper.getId());
Assert.assertNotNull("mapper.config exists", mapper.getConfig());
Assert.assertEquals("config retained", "offline_access", mapper.getConfig().get("role"));
// add duplicate mapper
Response error = provider.addMapper(mapper);
Assert.assertEquals("mapper unique name", 400, error.getStatus());
error.close();
// update mapper
mapper.getConfig().put("role", "master-realm.manage-realm");
provider.update(id, mapper);
assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.identityProviderMapperPath("google", id), mapper, ResourceType.IDENTITY_PROVIDER_MAPPER);
mapper = provider.getMapperById(id);
Assert.assertNotNull("mapperById not null", mapper);
Assert.assertEquals("config changed", "master-realm.manage-realm", mapper.getConfig().get("role"));
// delete mapper
provider.delete(id);
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.identityProviderMapperPath("google", id), ResourceType.IDENTITY_PROVIDER_MAPPER);
try {
provider.getMapperById(id);
Assert.fail("Should fail with NotFoundException");
} catch (NotFoundException e) {
// Expected
}
}
@Test
public void testInstalledIdentityProviders() {
Response response = realm.identityProviders().getIdentityProviders("oidc");
Assert.assertEquals("Status", 200, response.getStatus());
Map<String, String> body = response.readEntity(Map.class);
assertProviderInfo(body, "oidc", "OpenID Connect v1.0");
response = realm.identityProviders().getIdentityProviders("keycloak-oidc");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "keycloak-oidc", "Keycloak OpenID Connect");
response = realm.identityProviders().getIdentityProviders("saml");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "saml", "SAML v2.0");
response = realm.identityProviders().getIdentityProviders("google");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "google", "Google");
response = realm.identityProviders().getIdentityProviders("facebook");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "facebook", "Facebook");
response = realm.identityProviders().getIdentityProviders("github");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "github", "GitHub");
response = realm.identityProviders().getIdentityProviders("twitter");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "twitter", "Twitter");
response = realm.identityProviders().getIdentityProviders("linkedin");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "linkedin", "LinkedIn");
response = realm.identityProviders().getIdentityProviders("microsoft");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "microsoft", "Microsoft");
response = realm.identityProviders().getIdentityProviders("stackoverflow");
Assert.assertEquals("Status", 200, response.getStatus());
body = response.readEntity(Map.class);
assertProviderInfo(body, "stackoverflow", "StackOverflow");
response = realm.identityProviders().getIdentityProviders("nonexistent");
Assert.assertEquals("Status", 400, response.getStatus());
}
private void assertEqual(IdentityProviderRepresentation expected, IdentityProviderRepresentation actual) {
//System.out.println("expected: " + expected);
//System.out.println("actual: " + actual);
Assert.assertNotNull("expected IdentityProviderRepresentation not null", expected);
Assert.assertNotNull("actual IdentityProviderRepresentation not null", actual);
Assert.assertEquals("internalId", expected.getInternalId(), actual.getInternalId());
Assert.assertEquals("alias", expected.getAlias(), actual.getAlias());
Assert.assertEquals("providerId", expected.getProviderId(), actual.getProviderId());
Assert.assertEquals("enabled", expected.isEnabled(), actual.isEnabled());
Assert.assertEquals("firstBrokerLoginFlowAlias", expected.getFirstBrokerLoginFlowAlias(), actual.getFirstBrokerLoginFlowAlias());
Assert.assertEquals("config", expected.getConfig(), actual.getConfig());
}
private void assertCreatedSamlIdp(IdentityProviderRepresentation idp) {
//System.out.println("idp: " + idp);
Assert.assertNotNull("IdentityProviderRepresentation not null", idp);
Assert.assertNotNull("internalId", idp.getInternalId());
Assert.assertEquals("alias", "saml", idp.getAlias());
Assert.assertEquals("providerId", "saml", idp.getProviderId());
Assert.assertTrue("enabled", idp.isEnabled());
Assert.assertEquals("firstBrokerLoginFlowAlias", "first broker login",idp.getFirstBrokerLoginFlowAlias());
assertSamlConfig(idp.getConfig());
}
private void assertSamlConfig(Map<String, String> config) {
// import endpoint simply converts IDPSSODescriptor into key value pairs.
// check that saml-idp-metadata.xml was properly converted into key value pairs
//System.out.println(config);
assertThat(config.keySet(), containsInAnyOrder(
"validateSignature",
"singleLogoutServiceUrl",
"postBindingLogout",
"postBindingResponse",
"postBindingAuthnRequest",
"singleSignOnServiceUrl",
"wantAuthnRequestsSigned",
"signingCertificate",
"addExtensionsElementWithKeyInfo"
));
assertThat(config, hasEntry("validateSignature", "true"));
assertThat(config, hasEntry("singleLogoutServiceUrl", "http://localhost:8080/auth/realms/master/protocol/saml"));
assertThat(config, hasEntry("postBindingResponse", "true"));
assertThat(config, hasEntry("postBindingAuthnRequest", "true"));
assertThat(config, hasEntry("singleSignOnServiceUrl", "http://localhost:8080/auth/realms/master/protocol/saml"));
assertThat(config, hasEntry("wantAuthnRequestsSigned", "true"));
assertThat(config, hasEntry("addExtensionsElementWithKeyInfo", "false"));
assertThat(config, hasEntry(is("signingCertificate"), notNullValue()));
}
private void assertSamlImport(Map<String, String> config, String expectedSigningCertificates) {
assertSamlConfig(config);
assertThat(config, hasEntry("signingCertificate", expectedSigningCertificates));
}
private void assertSamlExport(String body) throws ParsingException, URISyntaxException {
//System.out.println(body);
Object entBody = new SAMLEntityDescriptorParser().parse(StaxParserUtil.getXMLEventReader(
new ByteArrayInputStream(body.getBytes(Charset.forName("utf-8")))));
Assert.assertEquals("Parsed export type", EntityDescriptorType.class, entBody.getClass());
EntityDescriptorType entity = (EntityDescriptorType) entBody;
Assert.assertEquals("EntityID", "http://localhost:8180/auth/realms/admin-client-test", entity.getEntityID());
Assert.assertNotNull("ChoiceType not null", entity.getChoiceType());
Assert.assertEquals("ChoiceType.size", 1, entity.getChoiceType().size());
List<EntityDescriptorType.EDTDescriptorChoiceType> descriptors = entity.getChoiceType().get(0).getDescriptors();
Assert.assertNotNull("Descriptors not null", descriptors);
Assert.assertEquals("Descriptors.size", 1, descriptors.size());
SPSSODescriptorType desc = descriptors.get(0).getSpDescriptor();
Assert.assertNotNull("SPSSODescriptor not null", desc);
Assert.assertTrue("AuthnRequestsSigned", desc.isAuthnRequestsSigned());
Set<String> expected = new HashSet(Arrays.asList(
"urn:oasis:names:tc:SAML:2.0:protocol",
"urn:oasis:names:tc:SAML:1.1:protocol",
"http://schemas.xmlsoap.org/ws/2003/07/secext"));
Set<String> actual = new HashSet(desc.getProtocolSupportEnumeration());
Assert.assertEquals("ProtocolSupportEnumeration", expected, actual);
Assert.assertNotNull("AssertionConsumerService not null", desc.getAssertionConsumerService());
Assert.assertEquals("AssertionConsumerService.size", 1, desc.getAssertionConsumerService().size());
IndexedEndpointType endpoint = desc.getAssertionConsumerService().get(0);
Assert.assertEquals("AssertionConsumerService.Location",
new URI("http://localhost:8180/auth/realms/admin-client-test/broker/saml/endpoint"), endpoint.getLocation());
Assert.assertEquals("AssertionConsumerService.Binding",
new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), endpoint.getBinding());
Assert.assertTrue("AssertionConsumerService.isDefault", endpoint.isIsDefault());
Assert.assertNotNull("SingleLogoutService not null", desc.getSingleLogoutService());
Assert.assertEquals("SingleLogoutService.size", 1, desc.getSingleLogoutService().size());
EndpointType sloEndpoint = desc.getSingleLogoutService().get(0);
Assert.assertEquals("SingleLogoutService.Location",
new URI("http://localhost:8180/auth/realms/admin-client-test/broker/saml/endpoint"), sloEndpoint.getLocation());
Assert.assertEquals("SingleLogoutService.Binding",
new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), sloEndpoint.getBinding());
Assert.assertNotNull("KeyDescriptor not null", desc.getKeyDescriptor());
Assert.assertEquals("KeyDescriptor.size", 1, desc.getKeyDescriptor().size());
KeyDescriptorType keyDesc = desc.getKeyDescriptor().get(0);
assertThat(keyDesc, notNullValue());
assertThat(keyDesc.getUse(), equalTo(KeyTypes.SIGNING));
NodeList cert = keyDesc.getKeyInfo().getElementsByTagNameNS(XMLSignature.XMLNS, "X509Certificate");
assertThat("KeyDescriptor.Signing.Cert existence", cert.getLength(), is(1));
}
private void assertProviderInfo(Map<String, String> info, String id, String name) {
System.out.println(info);
Assert.assertEquals("id", id, info.get("id"));
Assert.assertEquals("name", name, info.get("name"));
}
}