/*
* Copyright 2017 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.saml;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientsResource;
import org.keycloak.dom.saml.v2.assertion.NameIDType;
import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
import org.keycloak.dom.saml.v2.protocol.NameIDPolicyType;
import org.keycloak.dom.saml.v2.protocol.ResponseType;
import org.keycloak.protocol.saml.SamlConfigAttributes;
import org.keycloak.protocol.saml.SamlProtocol;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.testsuite.AbstractAuthTest;
import org.keycloak.testsuite.util.SamlClient;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.w3c.dom.Document;
import static org.hamcrest.Matchers.*;
import static org.keycloak.testsuite.util.SamlClient.*;
import static org.junit.Assert.assertThat;
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
import static org.keycloak.testsuite.util.Matchers.statusCodeIsHC;
/**
*
* @author hmlnarik
*/
public class AuthnRequestNameIdFormatTest extends AbstractSamlTest {
private void testLoginWithNameIdPolicy(Binding requestBinding, Binding responseBinding, NameIDPolicyType nameIDPolicy, Matcher<String> nameIdMatcher) throws Exception {
AuthnRequestType loginRep = createLoginRequestDocument(SAML_CLIENT_ID_SALES_POST, SAML_ASSERTION_CONSUMER_URL_SALES_POST, REALM_NAME);
loginRep.setProtocolBinding(requestBinding.getBindingUri());
loginRep.setNameIDPolicy(nameIDPolicy);
Document samlRequest = SAML2Request.convert(loginRep);
SAMLDocumentHolder res = login(bburkeUser, getAuthServerSamlEndpoint(REALM_NAME), samlRequest, null, requestBinding, responseBinding);
assertThat(res.getSamlObject(), notNullValue());
assertThat(res.getSamlObject(), instanceOf(ResponseType.class));
ResponseType rt = (ResponseType) res.getSamlObject();
assertThat(rt.getAssertions(), not(empty()));
assertThat(rt.getAssertions().get(0).getAssertion().getSubject().getSubType().getBaseID(), instanceOf(NameIDType.class));
NameIDType nameId = (NameIDType) rt.getAssertions().get(0).getAssertion().getSubject().getSubType().getBaseID();
assertThat(nameId.getValue(), nameIdMatcher);
}
@Test
public void testPostLoginNameIdPolicyUnspecified() throws Exception {
NameIDPolicyType nameIdPolicy = new NameIDPolicyType();
nameIdPolicy.setFormat(URI.create(JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get()));
testLoginWithNameIdPolicy(Binding.POST, Binding.POST, nameIdPolicy, is("bburke"));
}
@Test
public void testPostLoginNameIdPolicyEmail() throws Exception {
NameIDPolicyType nameIdPolicy = new NameIDPolicyType();
nameIdPolicy.setFormat(URI.create(JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get()));
testLoginWithNameIdPolicy(Binding.POST, Binding.POST, nameIdPolicy, is("bburke@redhat.com"));
}
@Test
public void testPostLoginNameIdPolicyPersistent() throws Exception {
NameIDPolicyType nameIdPolicy = new NameIDPolicyType();
nameIdPolicy.setFormat(URI.create(JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get()));
testLoginWithNameIdPolicy(Binding.POST, Binding.POST, nameIdPolicy, startsWith("G-"));
}
@Test
public void testPostLoginNoNameIdPolicyUnset() throws Exception {
testLoginWithNameIdPolicy(Binding.POST, Binding.POST, null, is("bburke"));
}
@Test
public void testRedirectLoginNameIdPolicyUnspecified() throws Exception {
NameIDPolicyType nameIdPolicy = new NameIDPolicyType();
nameIdPolicy.setFormat(URI.create(JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get()));
testLoginWithNameIdPolicy(Binding.REDIRECT, Binding.REDIRECT, nameIdPolicy, is("bburke"));
}
@Test
public void testRedirectLoginNameIdPolicyEmail() throws Exception {
NameIDPolicyType nameIdPolicy = new NameIDPolicyType();
nameIdPolicy.setFormat(URI.create(JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get()));
testLoginWithNameIdPolicy(Binding.REDIRECT, Binding.REDIRECT, nameIdPolicy, is("bburke@redhat.com"));
}
@Test
public void testRedirectLoginNameIdPolicyPersistent() throws Exception {
NameIDPolicyType nameIdPolicy = new NameIDPolicyType();
nameIdPolicy.setFormat(URI.create(JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get()));
testLoginWithNameIdPolicy(Binding.REDIRECT, Binding.REDIRECT, nameIdPolicy, startsWith("G-"));
}
@Test
public void testRedirectLoginNoNameIdPolicyUnset() throws Exception {
testLoginWithNameIdPolicy(Binding.REDIRECT, Binding.REDIRECT, null, is("bburke"));
}
@Test
public void testRedirectLoginNoNameIdPolicyForcePostBinding() throws Exception {
ClientsResource clients = adminClient.realm(REALM_NAME).clients();
List<ClientRepresentation> foundClients = clients.findByClientId("http://localhost:8081/sales-post/");
assertThat(foundClients, hasSize(1));
ClientResource clientRes = clients.get(foundClients.get(0).getId());
ClientRepresentation client = clientRes.toRepresentation();
client.getAttributes().put(SamlConfigAttributes.SAML_FORCE_POST_BINDING, "true");
clientRes.update(client);
testLoginWithNameIdPolicy(Binding.REDIRECT, Binding.POST, null, is("bburke"));
// Revert
client = clientRes.toRepresentation();
client.getAttributes().put(SamlConfigAttributes.SAML_FORCE_POST_BINDING, "false");
clientRes.update(client);
}
}