KEYCLOAK-4262 Test for rejected consent
This commit is contained in:
parent
b31c38a158
commit
119435ac76
8 changed files with 303 additions and 116 deletions
|
@ -118,12 +118,8 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
|
|||
modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "8080", System.getProperty("auth.server.http.port"));
|
||||
}
|
||||
|
||||
try {
|
||||
archive.add(new StringAsset(IOUtil.documentToString(doc)), adapterConfigPath);
|
||||
} catch (TransformerException e) {
|
||||
log.error("Can't transform document to String");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
archive.add(new StringAsset(IOUtil.documentToString(doc)), adapterConfigPath);
|
||||
|
||||
|
||||
// For running SAML tests it is necessary to have few dependencies on app-server side.
|
||||
// Few of them are not in adapter zip so we need to add them manually here
|
||||
|
@ -179,78 +175,68 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
|
|||
String dependency = testClass.getAnnotation(UseServletFilter.class).filterDependency();
|
||||
((WebArchive) archive).addAsLibraries(KeycloakDependenciesResolver.resolveDependencies((dependency + ":" + System.getProperty("project.version"))));
|
||||
|
||||
try {
|
||||
Document jbossXmlDoc = loadXML(archive.get(JBOSS_DEPLOYMENT_XML_PATH).getAsset().openStream());
|
||||
removeNodeByAttributeValue(jbossXmlDoc, "dependencies", "module", "name", "org.keycloak.keycloak-saml-core");
|
||||
removeNodeByAttributeValue(jbossXmlDoc, "dependencies", "module", "name", "org.keycloak.keycloak-adapter-spi");
|
||||
archive.add(new StringAsset((documentToString(jbossXmlDoc))), JBOSS_DEPLOYMENT_XML_PATH);
|
||||
} catch (TransformerException e) {
|
||||
log.error("Can't transform document to String");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Document jbossXmlDoc = loadXML(archive.get(JBOSS_DEPLOYMENT_XML_PATH).getAsset().openStream());
|
||||
removeNodeByAttributeValue(jbossXmlDoc, "dependencies", "module", "name", "org.keycloak.keycloak-saml-core");
|
||||
removeNodeByAttributeValue(jbossXmlDoc, "dependencies", "module", "name", "org.keycloak.keycloak-adapter-spi");
|
||||
archive.add(new StringAsset((documentToString(jbossXmlDoc))), JBOSS_DEPLOYMENT_XML_PATH);
|
||||
|
||||
}
|
||||
|
||||
protected void modifyWebXml(Archive<?> archive, TestClass testClass) {
|
||||
try {
|
||||
Document webXmlDoc = loadXML(
|
||||
archive.get(WEBXML_PATH).getAsset().openStream());
|
||||
if (isTomcatAppServer(testClass.getJavaClass())) {
|
||||
modifyDocElementValue(webXmlDoc, "auth-method", "KEYCLOAK", "BASIC");
|
||||
}
|
||||
|
||||
if (testClass.getJavaClass().isAnnotationPresent(UseServletFilter.class)) {
|
||||
|
||||
addFilterDependencies(archive, testClass);
|
||||
|
||||
//We need to add filter declaration to web.xml
|
||||
log.info("Adding filter to " + testClass.getAnnotation(UseServletFilter.class).filterClass() + " with mapping " + testClass.getAnnotation(UseServletFilter.class).filterPattern() + " for " + archive.getName());
|
||||
|
||||
Element filter = webXmlDoc.createElement("filter");
|
||||
Element filterName = webXmlDoc.createElement("filter-name");
|
||||
Element filterClass = webXmlDoc.createElement("filter-class");
|
||||
|
||||
filterName.setTextContent(testClass.getAnnotation(UseServletFilter.class).filterName());
|
||||
filterClass.setTextContent(testClass.getAnnotation(UseServletFilter.class).filterClass());
|
||||
|
||||
filter.appendChild(filterName);
|
||||
filter.appendChild(filterClass);
|
||||
appendChildInDocument(webXmlDoc, "web-app", filter);
|
||||
|
||||
Element filterMapping = webXmlDoc.createElement("filter-mapping");
|
||||
|
||||
|
||||
Element urlPattern = webXmlDoc.createElement("url-pattern");
|
||||
|
||||
filterName = webXmlDoc.createElement("filter-name");
|
||||
|
||||
filterName.setTextContent(testClass.getAnnotation(UseServletFilter.class).filterName());
|
||||
urlPattern.setTextContent(getElementTextContent(webXmlDoc, "web-app/security-constraint/web-resource-collection/url-pattern"));
|
||||
|
||||
filterMapping.appendChild(filterName);
|
||||
filterMapping.appendChild(urlPattern);
|
||||
|
||||
if (!testClass.getAnnotation(UseServletFilter.class).dispatcherType().isEmpty()) {
|
||||
Element dispatcher = webXmlDoc.createElement("dispatcher");
|
||||
dispatcher.setTextContent(testClass.getAnnotation(UseServletFilter.class).dispatcherType());
|
||||
filterMapping.appendChild(dispatcher);
|
||||
}
|
||||
appendChildInDocument(webXmlDoc, "web-app", filterMapping);
|
||||
|
||||
//finally we need to remove all keycloak related configuration from web.xml
|
||||
removeElementsFromDoc(webXmlDoc, "web-app", "security-constraint");
|
||||
removeElementsFromDoc(webXmlDoc, "web-app", "login-config");
|
||||
removeElementsFromDoc(webXmlDoc, "web-app", "security-role");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
archive.add(new StringAsset((documentToString(webXmlDoc))), WEBXML_PATH);
|
||||
} catch (TransformerException e) {
|
||||
log.error("Can't transform document to String");
|
||||
throw new RuntimeException(e);
|
||||
Document webXmlDoc = loadXML(
|
||||
archive.get(WEBXML_PATH).getAsset().openStream());
|
||||
if (isTomcatAppServer(testClass.getJavaClass())) {
|
||||
modifyDocElementValue(webXmlDoc, "auth-method", "KEYCLOAK", "BASIC");
|
||||
}
|
||||
|
||||
if (testClass.getJavaClass().isAnnotationPresent(UseServletFilter.class)) {
|
||||
|
||||
addFilterDependencies(archive, testClass);
|
||||
|
||||
//We need to add filter declaration to web.xml
|
||||
log.info("Adding filter to " + testClass.getAnnotation(UseServletFilter.class).filterClass() + " with mapping " + testClass.getAnnotation(UseServletFilter.class).filterPattern() + " for " + archive.getName());
|
||||
|
||||
Element filter = webXmlDoc.createElement("filter");
|
||||
Element filterName = webXmlDoc.createElement("filter-name");
|
||||
Element filterClass = webXmlDoc.createElement("filter-class");
|
||||
|
||||
filterName.setTextContent(testClass.getAnnotation(UseServletFilter.class).filterName());
|
||||
filterClass.setTextContent(testClass.getAnnotation(UseServletFilter.class).filterClass());
|
||||
|
||||
filter.appendChild(filterName);
|
||||
filter.appendChild(filterClass);
|
||||
appendChildInDocument(webXmlDoc, "web-app", filter);
|
||||
|
||||
Element filterMapping = webXmlDoc.createElement("filter-mapping");
|
||||
|
||||
|
||||
Element urlPattern = webXmlDoc.createElement("url-pattern");
|
||||
|
||||
filterName = webXmlDoc.createElement("filter-name");
|
||||
|
||||
filterName.setTextContent(testClass.getAnnotation(UseServletFilter.class).filterName());
|
||||
urlPattern.setTextContent(getElementTextContent(webXmlDoc, "web-app/security-constraint/web-resource-collection/url-pattern"));
|
||||
|
||||
filterMapping.appendChild(filterName);
|
||||
filterMapping.appendChild(urlPattern);
|
||||
|
||||
if (!testClass.getAnnotation(UseServletFilter.class).dispatcherType().isEmpty()) {
|
||||
Element dispatcher = webXmlDoc.createElement("dispatcher");
|
||||
dispatcher.setTextContent(testClass.getAnnotation(UseServletFilter.class).dispatcherType());
|
||||
filterMapping.appendChild(dispatcher);
|
||||
}
|
||||
appendChildInDocument(webXmlDoc, "web-app", filterMapping);
|
||||
|
||||
//finally we need to remove all keycloak related configuration from web.xml
|
||||
removeElementsFromDoc(webXmlDoc, "web-app", "security-constraint");
|
||||
removeElementsFromDoc(webXmlDoc, "web-app", "login-config");
|
||||
removeElementsFromDoc(webXmlDoc, "web-app", "security-role");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
archive.add(new StringAsset((documentToString(webXmlDoc))), WEBXML_PATH);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.xml.parsers.DocumentBuilder;
|
|||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
|
@ -89,13 +90,18 @@ public class IOUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static String documentToString(Document newDoc) throws TransformerException {
|
||||
DOMSource domSource = new DOMSource(newDoc);
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
StringWriter sw = new StringWriter();
|
||||
StreamResult sr = new StreamResult(sw);
|
||||
transformer.transform(domSource, sr);
|
||||
return sw.toString();
|
||||
public static String documentToString(Document newDoc) {
|
||||
try {
|
||||
DOMSource domSource = new DOMSource(newDoc);
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
StringWriter sw = new StringWriter();
|
||||
StreamResult sr = new StreamResult(sw);
|
||||
transformer.transform(domSource, sr);
|
||||
return sw.toString();
|
||||
} catch (TransformerException e) {
|
||||
log.error("Can't transform document to String");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void modifyDocElementAttribute(Document doc, String tagName, String attributeName, String regex, String replacement) {
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package org.keycloak.testsuite.saml;
|
||||
|
||||
import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
|
||||
import org.keycloak.protocol.saml.SamlProtocol;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.testsuite.AbstractAuthTest;
|
||||
import org.keycloak.testsuite.adapter.page.SAMLServlet;
|
||||
import org.keycloak.testsuite.util.SamlClient;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriBuilderException;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
|
||||
|
||||
/**
|
||||
* @author mhajas
|
||||
*/
|
||||
public class AbstractSamlTest extends AbstractAuthTest {
|
||||
|
||||
protected static final String REALM_NAME = "demo";
|
||||
|
||||
protected static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST = "http://localhost:8080/sales-post/";
|
||||
protected static final String SAML_CLIENT_ID_SALES_POST = "http://localhost:8081/sales-post/";
|
||||
|
||||
protected static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST_ENC = "http://localhost:8080/sales-post-enc/";
|
||||
protected static final String SAML_CLIENT_ID_SALES_POST_ENC = "http://localhost:8081/sales-post-enc/";
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
testRealms.add(loadRealm("/adapter-test/keycloak-saml/testsaml.json"));
|
||||
}
|
||||
|
||||
protected AuthnRequestType createLoginRequestDocument(String issuer, String assertionConsumerURL, String realmName) {
|
||||
return SamlClient.createLoginRequestDocument(issuer, assertionConsumerURL, getAuthServerSamlEndpoint(realmName));
|
||||
}
|
||||
|
||||
protected URI getAuthServerSamlEndpoint(String realm) throws IllegalArgumentException, UriBuilderException {
|
||||
return RealmsResource
|
||||
.protocolUrl(UriBuilder.fromUri(getAuthServerRoot()))
|
||||
.build(realm, SamlProtocol.LOGIN_PROTOCOL);
|
||||
}
|
||||
}
|
|
@ -60,27 +60,7 @@ import static org.keycloak.testsuite.util.Matchers.statusCodeIsHC;
|
|||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class AuthnRequestNameIdFormatTest extends AbstractAuthTest {
|
||||
|
||||
private static final String REALM_NAME = "demo";
|
||||
|
||||
private static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST = "http://localhost:8080/sales-post/";
|
||||
private static final String SAML_CLIENT_ID_SALES_POST = "http://localhost:8081/sales-post/";
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
testRealms.add(loadRealm("/adapter-test/keycloak-saml/testsaml.json"));
|
||||
}
|
||||
|
||||
public AuthnRequestType createLoginRequestDocument(String issuer, String assertionConsumerURL, String realmName) {
|
||||
return SamlClient.createLoginRequestDocument(issuer, assertionConsumerURL, getAuthServerSamlEndpoint(realmName));
|
||||
}
|
||||
|
||||
private URI getAuthServerSamlEndpoint(String realm) throws IllegalArgumentException, UriBuilderException {
|
||||
return RealmsResource
|
||||
.protocolUrl(UriBuilder.fromUri(getAuthServerRoot()))
|
||||
.build(realm, SamlProtocol.LOGIN_PROTOCOL);
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -53,12 +53,7 @@ import static org.keycloak.testsuite.util.IOUtil.loadRealm;
|
|||
* @author hmlnarik
|
||||
*/
|
||||
@Ignore
|
||||
public class ConcurrentAuthnRequestTest extends AbstractAuthTest {
|
||||
|
||||
private static final String REALM_NAME = "demo";
|
||||
|
||||
private static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST = "http://localhost:8080/sales-post/";
|
||||
private static final String SAML_CLIENT_ID_SALES_POST = "http://localhost:8081/sales-post/";
|
||||
public class ConcurrentAuthnRequestTest extends AbstractSamlTest {
|
||||
|
||||
public static final int ITERATIONS = 10000;
|
||||
public static final int CONCURRENT_THREADS = 5;
|
||||
|
@ -123,12 +118,6 @@ public class ConcurrentAuthnRequestTest extends AbstractAuthTest {
|
|||
return SamlClient.createLoginRequestDocument(issuer, assertionConsumerURL, getAuthServerSamlEndpoint(realmName));
|
||||
}
|
||||
|
||||
private URI getAuthServerSamlEndpoint(String realm) throws IllegalArgumentException, UriBuilderException {
|
||||
return RealmsResource
|
||||
.protocolUrl(UriBuilder.fromUri(getAuthServerRoot()))
|
||||
.build(realm, SamlProtocol.LOGIN_PROTOCOL);
|
||||
}
|
||||
|
||||
private void testLogin(Binding requestBinding) throws Exception {
|
||||
AuthnRequestType loginRep = createLoginRequestDocument(SAML_CLIENT_ID_SALES_POST, SAML_ASSERTION_CONSUMER_URL_SALES_POST, REALM_NAME);
|
||||
Document samlRequest = SAML2Request.convert(loginRep);
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package org.keycloak.testsuite.saml;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
import org.keycloak.saml.common.exceptions.ParsingException;
|
||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
import org.keycloak.testsuite.util.IOUtil;
|
||||
import org.keycloak.testsuite.util.SamlClient;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
|
||||
import static org.keycloak.testsuite.util.SamlClient.idpInitiatedLoginWithRequiredConsent;
|
||||
|
||||
/**
|
||||
* @author mhajas
|
||||
*/
|
||||
public class SamlConsentTest extends AbstractSamlTest {
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
testRealms.add(loadRealm("/adapter-test/keycloak-saml/testsaml.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signingOfRejectedConsentAssertionTest() throws ParsingException, ConfigurationException, ProcessingException {
|
||||
ClientRepresentation client = adminClient.realm(REALM_NAME)
|
||||
.clients()
|
||||
.findByClientId(SAML_CLIENT_ID_SALES_POST_ENC)
|
||||
.get(0);
|
||||
|
||||
adminClient.realm(REALM_NAME)
|
||||
.clients()
|
||||
.get(client.getId())
|
||||
.update(ClientBuilder.edit(client)
|
||||
.consentRequired(true)
|
||||
.attribute("saml.encrypt", "false") //remove after RHSSO-797
|
||||
.attribute("saml_idp_initiated_sso_url_name", "sales-post-enc")
|
||||
.attribute("saml_assertion_consumer_url_post", SAML_ASSERTION_CONSUMER_URL_SALES_POST_ENC + "saml")
|
||||
.build());
|
||||
|
||||
log.debug("Log in using idp initiated login");
|
||||
String idpInitiatedLogin = getAuthServerRoot() + "realms/" + REALM_NAME + "/protocol/saml/clients/sales-post-enc";
|
||||
SAMLDocumentHolder documentHolder = idpInitiatedLoginWithRequiredConsent(bburkeUser, URI.create(idpInitiatedLogin), SamlClient.Binding.POST, false);
|
||||
|
||||
assertThat(IOUtil.documentToString(documentHolder.getSamlDocument()), containsString("<dsig:Signature"));
|
||||
}
|
||||
}
|
|
@ -106,7 +106,10 @@ public class ClientBuilder {
|
|||
}
|
||||
|
||||
public ClientBuilder attribute(String name, String value) {
|
||||
Map<String, String> attributes = new HashMap<String, String>();
|
||||
Map<String, String> attributes = rep.getAttributes();
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<>();
|
||||
}
|
||||
attributes.put(name, value);
|
||||
rep.setAttributes(attributes);
|
||||
return this;
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.w3c.dom.Document;
|
|||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.keycloak.testsuite.admin.Users.getPasswordOf;
|
||||
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerContextRoot;
|
||||
import static org.keycloak.testsuite.util.Matchers.*;
|
||||
|
||||
/**
|
||||
|
@ -288,6 +289,58 @@ public class SamlClient {
|
|||
throw new IllegalArgumentException("Invalid login form: " + loginPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a GET/POST request for consent granting . The consent page is expected
|
||||
* to have at least input fields with id "kc-login" and "kc-cancel".
|
||||
* @param consentPage
|
||||
* @param consent
|
||||
* @return
|
||||
*/
|
||||
public static HttpUriRequest handleConsentPage(String consentPage, boolean consent) {
|
||||
org.jsoup.nodes.Document theLoginPage = Jsoup.parse(consentPage);
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<>();
|
||||
for (Element form : theLoginPage.getElementsByTag("form")) {
|
||||
String method = form.attr("method");
|
||||
String action = form.attr("action");
|
||||
boolean isPost = method != null && "post".equalsIgnoreCase(method);
|
||||
|
||||
for (Element input : form.getElementsByTag("input")) {
|
||||
if (Objects.equals(input.id(), "kc-login")) {
|
||||
if (consent)
|
||||
parameters.add(new BasicNameValuePair(input.attr("name"), input.attr("value")));
|
||||
} else if (Objects.equals(input.id(), "kc-cancel")) {
|
||||
if (!consent)
|
||||
parameters.add(new BasicNameValuePair(input.attr("name"), input.attr("value")));
|
||||
} else {
|
||||
parameters.add(new BasicNameValuePair(input.attr("name"), input.val()));
|
||||
}
|
||||
}
|
||||
|
||||
if (isPost) {
|
||||
HttpPost res = new HttpPost(getAuthServerContextRoot() + action);
|
||||
|
||||
UrlEncodedFormEntity formEntity;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
res.setEntity(formEntity);
|
||||
|
||||
return res;
|
||||
} else {
|
||||
UriBuilder b = UriBuilder.fromPath(action);
|
||||
for (NameValuePair parameter : parameters) {
|
||||
b.queryParam(parameter.getName(), parameter.getValue());
|
||||
}
|
||||
return new HttpGet(b.build());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid consent page: " + consentPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SAML login request document with the given parameters. See SAML <AuthnRequest> description for more details.
|
||||
* @param issuer
|
||||
|
@ -307,7 +360,7 @@ public class SamlClient {
|
|||
}
|
||||
|
||||
/**
|
||||
* Send request for login form and then login using user param
|
||||
* Send request for login form and then login using user param. This method is designed for clients without required consent
|
||||
* @param user
|
||||
* @param samlEndpoint
|
||||
* @param samlRequest
|
||||
|
@ -318,6 +371,38 @@ public class SamlClient {
|
|||
*/
|
||||
public static SAMLDocumentHolder login(UserRepresentation user, URI samlEndpoint,
|
||||
Document samlRequest, String relayState, Binding requestBinding, Binding expectedResponseBinding) {
|
||||
return login(user, samlEndpoint, samlRequest, relayState, requestBinding, expectedResponseBinding, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send request for login form and then login using user param. This method is designed for clients which requires consent
|
||||
* @param user
|
||||
* @param samlEndpoint
|
||||
* @param samlRequest
|
||||
* @param relayState
|
||||
* @param requestBinding
|
||||
* @param expectedResponseBinding
|
||||
* @return
|
||||
*/
|
||||
public static SAMLDocumentHolder loginWithRequiredConsent(UserRepresentation user, URI samlEndpoint,
|
||||
Document samlRequest, String relayState, Binding requestBinding, Binding expectedResponseBinding, boolean consent) {
|
||||
return login(user, samlEndpoint, samlRequest, relayState, requestBinding, expectedResponseBinding, true, consent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send request for login form and then login using user param. Check whether client requires consent and handle consent page.
|
||||
* @param user
|
||||
* @param samlEndpoint
|
||||
* @param samlRequest
|
||||
* @param relayState
|
||||
* @param requestBinding
|
||||
* @param expectedResponseBinding
|
||||
* @param consentRequired
|
||||
* @param consent
|
||||
* @return
|
||||
*/
|
||||
public static SAMLDocumentHolder login(UserRepresentation user, URI samlEndpoint,
|
||||
Document samlRequest, String relayState, Binding requestBinding, Binding expectedResponseBinding, boolean consentRequired, boolean consent) {
|
||||
CloseableHttpResponse response = null;
|
||||
SamlClient.RedirectStrategyWithSwitchableFollowRedirect strategy = new SamlClient.RedirectStrategyWithSwitchableFollowRedirect();
|
||||
try (CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(strategy).build()) {
|
||||
|
@ -334,6 +419,13 @@ public class SamlClient {
|
|||
|
||||
HttpUriRequest loginRequest = handleLoginPage(user, loginPageText);
|
||||
|
||||
if (consentRequired) {
|
||||
// Client requires consent
|
||||
response = client.execute(loginRequest, context);
|
||||
String consentPageText = EntityUtils.toString(response.getEntity(), "UTF-8");
|
||||
loginRequest = handleConsentPage(consentPageText, consent);
|
||||
}
|
||||
|
||||
strategy.setRedirectable(false);
|
||||
response = client.execute(loginRequest, context);
|
||||
|
||||
|
@ -349,13 +441,37 @@ public class SamlClient {
|
|||
}
|
||||
|
||||
/**
|
||||
* Send request for login form and then login using user param
|
||||
* Send request for login form and then login using user param for clients which doesn't require consent
|
||||
* @param user
|
||||
* @param idpInitiatedURI
|
||||
* @param expectedResponseBinding
|
||||
* @return
|
||||
*/
|
||||
public static SAMLDocumentHolder idpInitiatedLogin(UserRepresentation user, URI idpInitiatedURI, Binding expectedResponseBinding) {
|
||||
return idpInitiatedLogin(user, idpInitiatedURI, expectedResponseBinding, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send request for login form and then login using user param. For clients which requires consent
|
||||
* @param user
|
||||
* @param idpInitiatedURI
|
||||
* @param expectedResponseBinding
|
||||
* @param consent
|
||||
* @return
|
||||
*/
|
||||
public static SAMLDocumentHolder idpInitiatedLoginWithRequiredConsent(UserRepresentation user, URI idpInitiatedURI, Binding expectedResponseBinding, boolean consent) {
|
||||
return idpInitiatedLogin(user, idpInitiatedURI, expectedResponseBinding, true, consent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send request for login form and then login using user param. Checks whether client requires consent and handle consent page.
|
||||
* @param user
|
||||
* @param idpInitiatedURI
|
||||
* @param expectedResponseBinding
|
||||
* @param consent
|
||||
* @return
|
||||
*/
|
||||
public static SAMLDocumentHolder idpInitiatedLogin(UserRepresentation user, URI idpInitiatedURI, Binding expectedResponseBinding, boolean consentRequired, boolean consent) {
|
||||
CloseableHttpResponse response = null;
|
||||
SamlClient.RedirectStrategyWithSwitchableFollowRedirect strategy = new SamlClient.RedirectStrategyWithSwitchableFollowRedirect();
|
||||
try (CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(strategy).build()) {
|
||||
|
@ -373,6 +489,13 @@ public class SamlClient {
|
|||
|
||||
HttpUriRequest loginRequest = handleLoginPage(user, loginPageText);
|
||||
|
||||
if (consentRequired) {
|
||||
// Client requires consent
|
||||
response = client.execute(loginRequest, context);
|
||||
String consentPageText = EntityUtils.toString(response.getEntity(), "UTF-8");
|
||||
loginRequest = handleConsentPage(consentPageText, consent);
|
||||
}
|
||||
|
||||
strategy.setRedirectable(false);
|
||||
response = client.execute(loginRequest, context);
|
||||
|
||||
|
|
Loading…
Reference in a new issue