KEYCLOAK-10776 Add session expiration to Keycloak saml login response
This commit is contained in:
parent
4b18c6a117
commit
57a8fcb669
7 changed files with 246 additions and 3 deletions
|
@ -60,6 +60,7 @@ public class SAML2LoginResponseBuilder implements SamlProtocolExtensionsAwareBui
|
||||||
protected String issuer;
|
protected String issuer;
|
||||||
protected int subjectExpiration;
|
protected int subjectExpiration;
|
||||||
protected int assertionExpiration;
|
protected int assertionExpiration;
|
||||||
|
protected int sessionExpiration;
|
||||||
protected String nameId;
|
protected String nameId;
|
||||||
protected String nameIdFormat;
|
protected String nameIdFormat;
|
||||||
protected boolean multiValuedRoles;
|
protected boolean multiValuedRoles;
|
||||||
|
@ -98,6 +99,18 @@ public class SAML2LoginResponseBuilder implements SamlProtocolExtensionsAwareBui
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of time in seconds the idp session will be valid
|
||||||
|
* See SAML core specification 2.7.2 SessionNotOnOrAfter
|
||||||
|
*
|
||||||
|
* @param sessionExpiration Number of seconds the session should be valid
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SAML2LoginResponseBuilder sessionExpiration(int sessionExpiration) {
|
||||||
|
this.sessionExpiration = sessionExpiration;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Length of time in seconds the assertion is valid for
|
* Length of time in seconds the assertion is valid for
|
||||||
* See SAML core specification 2.5.1.2 NotOnOrAfter
|
* See SAML core specification 2.5.1.2 NotOnOrAfter
|
||||||
|
@ -217,6 +230,10 @@ public class SAML2LoginResponseBuilder implements SamlProtocolExtensionsAwareBui
|
||||||
|
|
||||||
AuthnStatementType authnStatement = StatementUtil.createAuthnStatement(XMLTimeUtil.getIssueInstant(),
|
AuthnStatementType authnStatement = StatementUtil.createAuthnStatement(XMLTimeUtil.getIssueInstant(),
|
||||||
authContextRef);
|
authContextRef);
|
||||||
|
|
||||||
|
if (sessionExpiration > 0)
|
||||||
|
authnStatement.setSessionNotOnOrAfter(XMLTimeUtil.add(authnStatement.getAuthnInstant(), sessionExpiration * 1000));
|
||||||
|
|
||||||
if (sessionIndex != null) authnStatement.setSessionIndex(sessionIndex);
|
if (sessionIndex != null) authnStatement.setSessionIndex(sessionIndex);
|
||||||
else authnStatement.setSessionIndex(assertion.getID());
|
else authnStatement.setSessionIndex(assertion.getID());
|
||||||
|
|
||||||
|
|
|
@ -390,8 +390,15 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
clientSession.setNote(SAML_NAME_ID_FORMAT, nameIdFormat);
|
clientSession.setNote(SAML_NAME_ID_FORMAT, nameIdFormat);
|
||||||
|
|
||||||
SAML2LoginResponseBuilder builder = new SAML2LoginResponseBuilder();
|
SAML2LoginResponseBuilder builder = new SAML2LoginResponseBuilder();
|
||||||
builder.requestID(requestID).destination(redirectUri).issuer(responseIssuer).assertionExpiration(realm.getAccessCodeLifespan()).subjectExpiration(realm.getAccessTokenLifespan())
|
builder.requestID(requestID)
|
||||||
.requestIssuer(clientSession.getClient().getClientId()).nameIdentifier(nameIdFormat, nameId).authMethod(JBossSAMLURIConstants.AC_UNSPECIFIED.get());
|
.destination(redirectUri)
|
||||||
|
.issuer(responseIssuer)
|
||||||
|
.assertionExpiration(realm.getAccessCodeLifespan())
|
||||||
|
.subjectExpiration(realm.getAccessTokenLifespan())
|
||||||
|
.sessionExpiration(realm.getSsoSessionMaxLifespan())
|
||||||
|
.requestIssuer(clientSession.getClient().getClientId())
|
||||||
|
.nameIdentifier(nameIdFormat, nameId)
|
||||||
|
.authMethod(JBossSAMLURIConstants.AC_UNSPECIFIED.get());
|
||||||
|
|
||||||
String sessionIndex = SamlSessionUtils.getSessionIndex(clientSession);
|
String sessionIndex = SamlSessionUtils.getSessionIndex(clientSession);
|
||||||
builder.sessionIndex(sessionIndex);
|
builder.sessionIndex(sessionIndex);
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
||||||
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
|
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
|
||||||
import org.keycloak.testsuite.adapter.page.Employee2Servlet;
|
import org.keycloak.testsuite.adapter.page.Employee2Servlet;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
|
||||||
import org.keycloak.testsuite.util.Matchers;
|
import org.keycloak.testsuite.util.Matchers;
|
||||||
import org.keycloak.testsuite.util.SamlClient;
|
import org.keycloak.testsuite.util.SamlClient;
|
||||||
import org.keycloak.testsuite.util.SamlClientBuilder;
|
import org.keycloak.testsuite.util.SamlClientBuilder;
|
||||||
|
@ -27,7 +28,10 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.keycloak.testsuite.saml.AbstractSamlTest.REALM_NAME;
|
||||||
import static org.keycloak.testsuite.util.Matchers.bodyHC;
|
import static org.keycloak.testsuite.util.Matchers.bodyHC;
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,4 +150,54 @@ public class SAMLServletSessionTimeoutTest extends AbstractSAMLServletAdapterTes
|
||||||
|
|
||||||
setAdapterAndServerTimeOffset(0, employee2ServletPage.toString());
|
setAdapterAndServerTimeOffset(0, employee2ServletPage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeycloakReturnsSessionNotOnOrAfter() throws Exception {
|
||||||
|
sessionNotOnOrAfter.set(null);
|
||||||
|
|
||||||
|
try(AutoCloseable c = new RealmAttributeUpdater(adminClient.realm(REALM_NAME))
|
||||||
|
.updateWith(r -> r.setSsoSessionMaxLifespan(SESSION_LENGTH_IN_SECONDS))
|
||||||
|
.update()) {
|
||||||
|
beginAuthenticationAndLogin()
|
||||||
|
.processSamlResponse(SamlClient.Binding.POST) // Process response
|
||||||
|
.transformObject(ob -> { // Check sessionNotOnOrAfter is present and it has correct value
|
||||||
|
assertThat(ob, Matchers.isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
|
||||||
|
ResponseType resp = (ResponseType) ob;
|
||||||
|
|
||||||
|
Set<StatementAbstractType> statements = resp.getAssertions().get(0).getAssertion().getStatements();
|
||||||
|
|
||||||
|
AuthnStatementType authType = (AuthnStatementType) statements.stream()
|
||||||
|
.filter(statement -> statement instanceof AuthnStatementType)
|
||||||
|
.findFirst().orElseThrow(() -> new RuntimeException("SamlReponse doesn't contain AuthStatement"));
|
||||||
|
|
||||||
|
assertThat(authType.getSessionNotOnOrAfter(), notNullValue());
|
||||||
|
XMLGregorianCalendar expectedSessionTimeout = XMLTimeUtil.add(authType.getAuthnInstant(), SESSION_LENGTH_IN_SECONDS * 1000);
|
||||||
|
assertThat(authType.getSessionNotOnOrAfter(), is(expectedSessionTimeout));
|
||||||
|
sessionNotOnOrAfter.set(expectedSessionTimeout.toString());
|
||||||
|
|
||||||
|
return ob;
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
.navigateTo(employee2ServletPage.buildUri())
|
||||||
|
.assertResponse(response -> // Check that session is still valid within sessionTimeout limit
|
||||||
|
assertThat(response, // Cannot use matcher as sessionNotOnOrAfter variable is not set in time of creating matcher
|
||||||
|
bodyHC(allOf(containsString("principal=bburke"),
|
||||||
|
containsString("SessionNotOnOrAfter: " + sessionNotOnOrAfter.get())))))
|
||||||
|
.addStep(() -> setAdapterAndServerTimeOffset(KEYCLOAK_SESSION_TIMEOUT, employee2ServletPage.toString())) // Move in time after sessionNotOnOrAfter and keycloak session
|
||||||
|
.navigateTo(employee2ServletPage.buildUri())
|
||||||
|
.processSamlResponse(SamlClient.Binding.POST) // AuthnRequest should be send
|
||||||
|
.transformObject(ob -> {
|
||||||
|
assertThat(ob, Matchers.isSamlAuthnRequest());
|
||||||
|
return ob;
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
.followOneRedirect() // There is a redirect on Keycloak side
|
||||||
|
.assertResponse(Matchers.bodyHC(containsString("form id=\"kc-form-login\"")))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
setAdapterAndServerTimeOffset(0, employee2ServletPage.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.keycloak.testsuite.broker;
|
||||||
|
|
||||||
|
import org.keycloak.protocol.saml.SamlProtocol;
|
||||||
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
import javax.ws.rs.core.UriBuilderException;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
public abstract class AbstractSamlBrokerTest extends AbstractInitializedBaseBrokerTest {
|
||||||
|
|
||||||
|
protected URI getAuthServerSamlEndpoint(String realm) throws IllegalArgumentException, UriBuilderException {
|
||||||
|
return RealmsResource
|
||||||
|
.protocolUrl(UriBuilder.fromUri(getAuthServerRoot()))
|
||||||
|
.build(realm, SamlProtocol.LOGIN_PROTOCOL);
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.keycloak.broker.saml.SAMLIdentityProviderConfig.*;
|
import static org.keycloak.broker.saml.SAMLIdentityProviderConfig.*;
|
||||||
|
import static org.keycloak.protocol.saml.SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE;
|
||||||
|
import static org.keycloak.protocol.saml.SamlProtocol.SAML_IDP_INITIATED_SSO_URL_NAME;
|
||||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.*;
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.*;
|
||||||
import static org.keycloak.testsuite.broker.BrokerTestTools.*;
|
import static org.keycloak.testsuite.broker.BrokerTestTools.*;
|
||||||
|
|
||||||
|
@ -75,7 +77,7 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
|
||||||
attributes.put(SamlConfigAttributes.SAML_AUTHNSTATEMENT, "true");
|
attributes.put(SamlConfigAttributes.SAML_AUTHNSTATEMENT, "true");
|
||||||
attributes.put(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE,
|
attributes.put(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE,
|
||||||
getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint");
|
getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint");
|
||||||
attributes.put(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE,
|
attributes.put(SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE,
|
||||||
getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint");
|
getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint");
|
||||||
attributes.put(SamlConfigAttributes.SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE, "true");
|
attributes.put(SamlConfigAttributes.SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE, "true");
|
||||||
attributes.put(SamlConfigAttributes.SAML_NAME_ID_FORMAT_ATTRIBUTE, "username");
|
attributes.put(SamlConfigAttributes.SAML_NAME_ID_FORMAT_ATTRIBUTE, "username");
|
||||||
|
@ -168,6 +170,8 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
|
||||||
.addRedirectUri("https://localhost:8543/sales-post/*")
|
.addRedirectUri("https://localhost:8543/sales-post/*")
|
||||||
.attribute(SamlConfigAttributes.SAML_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE)
|
.attribute(SamlConfigAttributes.SAML_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE)
|
||||||
.attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE)
|
.attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE)
|
||||||
|
.attribute(SAML_IDP_INITIATED_SSO_URL_NAME, "sales-post")
|
||||||
|
.attribute(SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE, "https://localhost:8180/sales-post/saml")
|
||||||
.build(),
|
.build(),
|
||||||
ClientBuilder.create()
|
ClientBuilder.create()
|
||||||
.id("broker-app")
|
.id("broker-app")
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
package org.keycloak.testsuite.broker;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
|
||||||
|
import org.keycloak.dom.saml.v2.assertion.StatementAbstractType;
|
||||||
|
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
||||||
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
|
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
|
||||||
|
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
||||||
|
import org.keycloak.testsuite.util.Matchers;
|
||||||
|
import org.keycloak.testsuite.util.SamlClient;
|
||||||
|
import org.keycloak.testsuite.util.SamlClientBuilder;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_SAML_ALIAS;
|
||||||
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME;
|
||||||
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_EMAIL;
|
||||||
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_LOGIN;
|
||||||
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_PASSWORD;
|
||||||
|
|
||||||
|
public class KcSamlBrokerSessionNotOnOrAfterTest extends AbstractSamlBrokerTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BrokerConfiguration getBrokerConfiguration() {
|
||||||
|
return KcSamlBrokerConfiguration.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConsumerIdpInitiatedLoginContainsSessionNotOnOrAfter() throws Exception {
|
||||||
|
SAMLDocumentHolder samlResponse = new SamlClientBuilder()
|
||||||
|
.idpInitiatedLogin(getAuthServerSamlEndpoint(REALM_CONS_NAME), "sales-post").build()
|
||||||
|
// Request login via kc-saml-idp
|
||||||
|
.login().idp(IDP_SAML_ALIAS).build()
|
||||||
|
|
||||||
|
.processSamlResponse(SamlClient.Binding.POST) // AuthnRequest to producer IdP
|
||||||
|
.targetAttributeSamlRequest()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
// Login in provider realm
|
||||||
|
.login().user(USER_LOGIN, USER_PASSWORD).build()
|
||||||
|
|
||||||
|
// Send the response to the consumer realm
|
||||||
|
.processSamlResponse(SamlClient.Binding.POST).build()
|
||||||
|
|
||||||
|
// Create account in comsumer realm
|
||||||
|
.updateProfile().username(USER_LOGIN).email(USER_EMAIL).firstName("Firstname").lastName("Lastname").build()
|
||||||
|
.followOneRedirect()
|
||||||
|
|
||||||
|
// Obtain the response sent to the app
|
||||||
|
.getSamlResponse(SamlClient.Binding.POST);
|
||||||
|
|
||||||
|
assertThat(samlResponse.getSamlObject(), Matchers.isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
|
||||||
|
ResponseType resp = (ResponseType) samlResponse.getSamlObject();
|
||||||
|
Set<StatementAbstractType> statements = resp.getAssertions().get(0).getAssertion().getStatements();
|
||||||
|
|
||||||
|
AuthnStatementType authType = statements.stream()
|
||||||
|
.filter(statement -> statement instanceof AuthnStatementType)
|
||||||
|
.map(s -> (AuthnStatementType) s)
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
|
||||||
|
assertThat(authType, notNullValue());
|
||||||
|
assertThat(authType.getSessionNotOnOrAfter(), notNullValue());
|
||||||
|
assertThat(authType.getSessionNotOnOrAfter(), is(XMLTimeUtil.add(authType.getAuthnInstant(), adminClient.realm(REALM_CONS_NAME).toRepresentation().getSsoSessionMaxLifespan() * 1000)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package org.keycloak.testsuite.saml;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.dom.saml.v2.SAML2Object;
|
||||||
|
import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
|
||||||
|
import org.keycloak.dom.saml.v2.assertion.StatementAbstractType;
|
||||||
|
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
||||||
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
|
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
||||||
|
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
|
||||||
|
import org.keycloak.testsuite.util.Matchers;
|
||||||
|
import org.keycloak.testsuite.util.SamlClient;
|
||||||
|
import org.keycloak.testsuite.util.SamlClientBuilder;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mhajas
|
||||||
|
*/
|
||||||
|
public class SessionNotOnOrAfterTest extends AbstractSamlTest {
|
||||||
|
|
||||||
|
private static final Integer SSO_MAX_LIFESPAN = 3602;
|
||||||
|
|
||||||
|
private SAML2Object checkSessionNotOnOrAfter(SAML2Object ob) {
|
||||||
|
assertThat(ob, Matchers.isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
|
||||||
|
ResponseType resp = (ResponseType) ob;
|
||||||
|
Set<StatementAbstractType> statements = resp.getAssertions().get(0).getAssertion().getStatements();
|
||||||
|
|
||||||
|
AuthnStatementType authType = statements.stream()
|
||||||
|
.filter(statement -> statement instanceof AuthnStatementType)
|
||||||
|
.map(s -> (AuthnStatementType) s)
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
|
||||||
|
assertThat(authType, notNullValue());
|
||||||
|
assertThat(authType.getSessionNotOnOrAfter(), notNullValue());
|
||||||
|
assertThat(authType.getSessionNotOnOrAfter(), is(XMLTimeUtil.add(authType.getAuthnInstant(), SSO_MAX_LIFESPAN * 1000)));
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSamlResponseContainsSessionNotOnOrAfterIdpInitiatedLogin() throws Exception {
|
||||||
|
try(AutoCloseable c = new RealmAttributeUpdater(adminClient.realm(REALM_NAME))
|
||||||
|
.updateWith(r -> r.setSsoSessionMaxLifespan(SSO_MAX_LIFESPAN))
|
||||||
|
.update()) {
|
||||||
|
new SamlClientBuilder()
|
||||||
|
.idpInitiatedLogin(getAuthServerSamlEndpoint(REALM_NAME), "sales-post").build()
|
||||||
|
.login().user(bburkeUser).build()
|
||||||
|
.processSamlResponse(SamlClient.Binding.POST)
|
||||||
|
.transformObject(this::checkSessionNotOnOrAfter)
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSamlResponseContainsSessionNotOnOrAfterAuthnLogin() throws Exception {
|
||||||
|
try(AutoCloseable c = new RealmAttributeUpdater(adminClient.realm(REALM_NAME))
|
||||||
|
.updateWith(r -> r.setSsoSessionMaxLifespan(SSO_MAX_LIFESPAN))
|
||||||
|
.update()) {
|
||||||
|
new SamlClientBuilder()
|
||||||
|
.authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST, SAML_ASSERTION_CONSUMER_URL_SALES_POST, SamlClient.Binding.POST)
|
||||||
|
.build()
|
||||||
|
.login().user(bburkeUser).build()
|
||||||
|
.processSamlResponse(SamlClient.Binding.POST)
|
||||||
|
.transformObject(this::checkSessionNotOnOrAfter)
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue