saml frontchannel logout
This commit is contained in:
parent
15feb39ecc
commit
ea3bba98aa
15 changed files with 182 additions and 19 deletions
|
@ -22,6 +22,7 @@ public class ApplicationRepresentation {
|
|||
protected Integer notBefore;
|
||||
protected Boolean bearerOnly;
|
||||
protected Boolean publicClient;
|
||||
protected Boolean frontchannelLogout;
|
||||
protected String protocol;
|
||||
protected Map<String, String> attributes;
|
||||
protected Boolean fullScopeAllowed;
|
||||
|
@ -179,4 +180,12 @@ public class ApplicationRepresentation {
|
|||
public void setRegisteredNodes(Map<String, Integer> registeredNodes) {
|
||||
this.registeredNodes = registeredNodes;
|
||||
}
|
||||
|
||||
public Boolean isFrontchannelLogout() {
|
||||
return frontchannelLogout;
|
||||
}
|
||||
|
||||
public void setFrontchannelLogout(Boolean frontchannelLogout) {
|
||||
this.frontchannelLogout = frontchannelLogout;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ public class OAuthClientRepresentation {
|
|||
protected Map<String, String> attributes;
|
||||
protected Boolean directGrantsOnly;
|
||||
protected Boolean fullScopeAllowed;
|
||||
protected Boolean frontchannelLogout;
|
||||
|
||||
|
||||
public String getId() {
|
||||
|
@ -126,4 +127,12 @@ public class OAuthClientRepresentation {
|
|||
public void setAttributes(Map<String, String> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public Boolean isFrontchannelLogout() {
|
||||
return frontchannelLogout;
|
||||
}
|
||||
|
||||
public void setFrontchannelLogout(Boolean frontchannelLogout) {
|
||||
this.frontchannelLogout = frontchannelLogout;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,6 +230,7 @@ public class ModelToRepresentation {
|
|||
rep.setEnabled(applicationModel.isEnabled());
|
||||
rep.setAdminUrl(applicationModel.getManagementUrl());
|
||||
rep.setPublicClient(applicationModel.isPublicClient());
|
||||
rep.setFrontchannelLogout(applicationModel.isFrontchannelLogout());
|
||||
rep.setProtocol(applicationModel.getProtocol());
|
||||
rep.setAttributes(applicationModel.getAttributes());
|
||||
rep.setFullScopeAllowed(applicationModel.isFullScopeAllowed());
|
||||
|
@ -266,6 +267,7 @@ public class ModelToRepresentation {
|
|||
rep.setName(model.getClientId());
|
||||
rep.setEnabled(model.isEnabled());
|
||||
rep.setPublicClient(model.isPublicClient());
|
||||
rep.setFrontchannelLogout(model.isFrontchannelLogout());
|
||||
rep.setProtocol(model.getProtocol());
|
||||
rep.setAttributes(model.getAttributes());
|
||||
rep.setFullScopeAllowed(model.isFullScopeAllowed());
|
||||
|
|
|
@ -372,6 +372,7 @@ public class RepresentationToModel {
|
|||
applicationModel.setBaseUrl(resourceRep.getBaseUrl());
|
||||
if (resourceRep.isBearerOnly() != null) applicationModel.setBearerOnly(resourceRep.isBearerOnly());
|
||||
if (resourceRep.isPublicClient() != null) applicationModel.setPublicClient(resourceRep.isPublicClient());
|
||||
if (resourceRep.isFrontchannelLogout() != null) applicationModel.setFrontchannelLogout(resourceRep.isFrontchannelLogout());
|
||||
if (resourceRep.getProtocol() != null) applicationModel.setProtocol(resourceRep.getProtocol());
|
||||
if (resourceRep.isFullScopeAllowed() != null) {
|
||||
applicationModel.setFullScopeAllowed(resourceRep.isFullScopeAllowed());
|
||||
|
@ -458,6 +459,7 @@ public class RepresentationToModel {
|
|||
if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
|
||||
if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient());
|
||||
if (rep.isFullScopeAllowed() != null) resource.setFullScopeAllowed(rep.isFullScopeAllowed());
|
||||
if (rep.isFrontchannelLogout() != null) resource.setFrontchannelLogout(rep.isFrontchannelLogout());
|
||||
if (rep.getAdminUrl() != null) resource.setManagementUrl(rep.getAdminUrl());
|
||||
if (rep.getBaseUrl() != null) resource.setBaseUrl(rep.getBaseUrl());
|
||||
if (rep.isSurrogateAuthRequired() != null) resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
|
||||
|
@ -579,6 +581,7 @@ public class RepresentationToModel {
|
|||
if (rep.getName() != null) model.setClientId(rep.getName());
|
||||
if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
|
||||
if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient());
|
||||
if (rep.isFrontchannelLogout() != null) model.setFrontchannelLogout(rep.isFrontchannelLogout());
|
||||
if (rep.isFullScopeAllowed() != null) model.setFullScopeAllowed(rep.isFullScopeAllowed());
|
||||
if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
|
||||
if (rep.getClaims() != null) {
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -21,7 +21,7 @@
|
|||
<resteasy.version.latest>3.0.9.Final</resteasy.version.latest>
|
||||
<!-- <undertow.version>1.1.0.Final</undertow.version> -->
|
||||
<undertow.version>1.1.1.Final</undertow.version>
|
||||
<picketlink.version>2.7.0.CR2</picketlink.version>
|
||||
<picketlink.version>2.7.0.CR3</picketlink.version>
|
||||
<picketbox.ldap.version>1.0.2.Final</picketbox.ldap.version>
|
||||
<mongo.driver.version>2.11.3</mongo.driver.version>
|
||||
<jboss.logging.version>3.1.4.GA</jboss.logging.version>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.picketlink.common.constants.GeneralConstants;
|
||||
import org.picketlink.common.constants.JBossSAMLConstants;
|
||||
import org.picketlink.common.constants.JBossSAMLURIConstants;
|
||||
|
@ -38,6 +39,7 @@ import static org.picketlink.common.util.StringUtil.isNotNull;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class SAML2BindingBuilder<T extends SAML2BindingBuilder> {
|
||||
protected static final Logger logger = Logger.getLogger(SAML2BindingBuilder.class);
|
||||
|
||||
protected KeyPair signingKeyPair;
|
||||
protected X509Certificate signingCertificate;
|
||||
|
@ -148,6 +150,9 @@ public class SAML2BindingBuilder<T extends SAML2BindingBuilder> {
|
|||
public Response request() throws ConfigurationException, ProcessingException, IOException {
|
||||
return buildResponse(document, destination, true);
|
||||
}
|
||||
public Response request(String actionUrl) throws ConfigurationException, ProcessingException, IOException {
|
||||
return buildResponse(document, actionUrl, true);
|
||||
}
|
||||
public Response response() throws ConfigurationException, ProcessingException, IOException {
|
||||
return buildResponse(document, destination, false);
|
||||
}
|
||||
|
@ -186,13 +191,16 @@ public class SAML2BindingBuilder<T extends SAML2BindingBuilder> {
|
|||
return response(destination, false);
|
||||
}
|
||||
|
||||
public Response request(String redirect) throws ProcessingException, ConfigurationException, IOException {
|
||||
return response(redirect, true);
|
||||
}
|
||||
public Response request() throws ProcessingException, ConfigurationException, IOException {
|
||||
return response(destination, true);
|
||||
}
|
||||
|
||||
private Response response(String redirectUri, boolean asRequest) throws ProcessingException, ConfigurationException, IOException {
|
||||
URI uri = responseUri(redirectUri, asRequest);
|
||||
|
||||
if (logger.isDebugEnabled()) logger.trace("redirect-binding uri: " + uri.toString());
|
||||
CacheControl cacheControl = new CacheControl();
|
||||
cacheControl.setNoCache(true);
|
||||
return Response.status(302).location(uri)
|
||||
|
@ -339,7 +347,9 @@ public class SAML2BindingBuilder<T extends SAML2BindingBuilder> {
|
|||
}
|
||||
|
||||
protected String base64Encoded(Document document) throws ConfigurationException, ProcessingException, IOException {
|
||||
byte[] responseBytes = org.picketlink.identity.federation.core.saml.v2.util.DocumentUtil.getDocumentAsString(document).getBytes("UTF-8");
|
||||
String documentAsString = org.picketlink.identity.federation.core.saml.v2.util.DocumentUtil.getDocumentAsString(document);
|
||||
logger.debugv("saml docment: {0}", documentAsString);
|
||||
byte[] responseBytes = documentAsString.getBytes("UTF-8");
|
||||
|
||||
return RedirectBindingUtil.deflateBase64URLEncode(responseBytes);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,13 @@ public class SAML2LogoutRequestBuilder extends SAML2BindingBuilder<SAML2LogoutRe
|
|||
nameID.setFormat(URI.create(nameIDFormat));
|
||||
lort.setNameID(nameID);
|
||||
|
||||
if (issuer != null) {
|
||||
NameIDType issuerID = new NameIDType();
|
||||
issuerID.setValue(issuer);
|
||||
lort.setIssuer(issuerID);
|
||||
}
|
||||
|
||||
|
||||
long assertionValidity = PicketLinkCoreSTS.instance().getConfiguration().getIssuedTokenTimeout();
|
||||
|
||||
lort.setNotOnOrAfter(XMLTimeUtil.add(lort.getIssueInstant(), assertionValidity));
|
||||
|
|
|
@ -307,9 +307,10 @@ public class SamlProtocol implements LoginProtocol {
|
|||
SAML2LogoutRequestBuilder logoutBuilder = createLogoutRequest(clientSession, client);
|
||||
try {
|
||||
if (isLogoutPostBindingForClient(app)) {
|
||||
return logoutBuilder.postBinding().response(bindingUri);
|
||||
return logoutBuilder.postBinding().request(bindingUri);
|
||||
} else {
|
||||
return logoutBuilder.redirectBinding().response(bindingUri);
|
||||
logger.debug("frontchannel redirect binding");
|
||||
return logoutBuilder.redirectBinding().request(bindingUri);
|
||||
}
|
||||
} catch (ConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
@ -325,6 +326,7 @@ public class SamlProtocol implements LoginProtocol {
|
|||
|
||||
@Override
|
||||
public Response finishLogout(UserSessionModel userSession) {
|
||||
logger.debug("finishLogout");
|
||||
SAML2LogoutResponseBuilder builder = new SAML2LogoutResponseBuilder();
|
||||
builder.logoutRequestID(userSession.getNote(SAML_LOGOUT_REQUEST_ID));
|
||||
builder.destination(userSession.getNote(SAML_LOGOUT_ISSUER));
|
||||
|
|
|
@ -136,6 +136,7 @@ public class SamlService {
|
|||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request");
|
||||
}
|
||||
logger.debug("logout response");
|
||||
return authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection);
|
||||
}
|
||||
|
||||
|
@ -183,12 +184,15 @@ public class SamlService {
|
|||
event.error(Errors.INVALID_SIGNATURE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid requester.");
|
||||
}
|
||||
logger.debug("verified request");
|
||||
if (samlObject instanceof AuthnRequestType) {
|
||||
logger.debug("** login request");
|
||||
event.event(EventType.LOGIN);
|
||||
// Get the SAML Request Message
|
||||
AuthnRequestType authn = (AuthnRequestType) samlObject;
|
||||
return loginRequest(relayState, authn, client);
|
||||
} else if (samlObject instanceof LogoutRequestType) {
|
||||
logger.debug("** logout request");
|
||||
event.event(EventType.LOGOUT);
|
||||
LogoutRequestType logout = (LogoutRequestType) samlObject;
|
||||
return logoutRequest(logout, client, relayState);
|
||||
|
@ -306,6 +310,13 @@ public class SamlService {
|
|||
userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING, logoutBinding);
|
||||
userSession.setNote(SamlProtocol.SAML_LOGOUT_ISSUER, logoutRequest.getIssuer().getValue());
|
||||
userSession.setNote(AuthenticationManager.KEYCLOAK_LOGOUT_PROTOCOL, SamlProtocol.LOGIN_PROTOCOL);
|
||||
// remove client from logout requests
|
||||
for (ClientSessionModel clientSession : userSession.getClientSessions()) {
|
||||
if (clientSession.getClient().getId().equals(client.getId())) {
|
||||
clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT);
|
||||
}
|
||||
}
|
||||
logger.debug("browser Logout");
|
||||
return authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection);
|
||||
}
|
||||
|
||||
|
@ -450,6 +461,7 @@ public class SamlService {
|
|||
public Response redirectBinding(@QueryParam(GeneralConstants.SAML_REQUEST_KEY) String samlRequest,
|
||||
@QueryParam(GeneralConstants.SAML_RESPONSE_KEY) String samlResponse,
|
||||
@QueryParam(GeneralConstants.RELAY_STATE) String relayState) {
|
||||
logger.debug("SAML GET");
|
||||
return new RedirectBindingProtocol().execute(samlRequest, samlResponse, relayState);
|
||||
}
|
||||
|
||||
|
@ -461,6 +473,7 @@ public class SamlService {
|
|||
public Response postBinding(@FormParam(GeneralConstants.SAML_REQUEST_KEY) String samlRequest,
|
||||
@FormParam(GeneralConstants.SAML_RESPONSE_KEY) String samlResponse,
|
||||
@FormParam(GeneralConstants.RELAY_STATE) String relayState) {
|
||||
logger.debug("SAML POST");
|
||||
return new PostBindingProtocol().execute(samlRequest, samlResponse, relayState);
|
||||
}
|
||||
|
||||
|
|
|
@ -115,19 +115,21 @@ public class AuthenticationManager {
|
|||
List<ClientSessionModel> redirectClients = new LinkedList<ClientSessionModel>();
|
||||
for (ClientSessionModel clientSession : userSession.getClientSessions()) {
|
||||
ClientModel client = clientSession.getClient();
|
||||
if (clientSession.getAction() == ClientSessionModel.Action.LOGGED_OUT) continue;
|
||||
if (client.isFrontchannelLogout()) {
|
||||
String authMethod = clientSession.getAuthMethod();
|
||||
if (authMethod == null) continue; // must be a keycloak service like account
|
||||
redirectClients.add(clientSession);
|
||||
continue;
|
||||
}
|
||||
if (client instanceof ApplicationModel && !client.isFrontchannelLogout() && clientSession.getAction() != ClientSessionModel.Action.LOGGED_OUT) {
|
||||
if (client instanceof ApplicationModel && !client.isFrontchannelLogout()) {
|
||||
String authMethod = clientSession.getAuthMethod();
|
||||
if (authMethod == null) continue; // must be a keycloak service like account
|
||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
|
||||
protocol.setRealm(realm)
|
||||
.setUriInfo(uriInfo);
|
||||
try {
|
||||
logger.debugv("backchannel logout to: {0}", client.getClientId());
|
||||
protocol.backchannelLogout(userSession, clientSession);
|
||||
clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT);
|
||||
} catch (Exception e) {
|
||||
|
@ -147,8 +149,12 @@ public class AuthenticationManager {
|
|||
// setting this to logged out cuz I"m not sure protocols can always verify that the client was logged out or not
|
||||
nextRedirectClient.setAction(ClientSessionModel.Action.LOGGED_OUT);
|
||||
try {
|
||||
logger.debugv("frontchannel logout to: {0}", nextRedirectClient.getClient().getClientId());
|
||||
Response response = protocol.frontchannelLogout(userSession, nextRedirectClient);
|
||||
if (response != null) return response;
|
||||
if (response != null) {
|
||||
logger.debug("returning frontchannel logout request to client");
|
||||
return response;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to logout client, continuing", e);
|
||||
}
|
||||
|
|
|
@ -328,7 +328,7 @@ public class ResourceAdminManager {
|
|||
return new GlobalRequestResult();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) logger.info("Sending push revocation to URLS: " + mgmtUrls);
|
||||
if (logger.isDebugEnabled()) logger.debug("Sending push revocation to URLS: " + mgmtUrls);
|
||||
|
||||
// Propagate this to all hosts
|
||||
GlobalRequestResult result = new GlobalRequestResult();
|
||||
|
|
|
@ -54,6 +54,7 @@ public class SamlBindingTest {
|
|||
initializeSamlSecuredWar("/saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader);
|
||||
initializeSamlSecuredWar("/saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader);
|
||||
initializeSamlSecuredWar("/saml/signed-get", "/employee-sig", "employee-sig.war", classLoader);
|
||||
initializeSamlSecuredWar("/saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader);
|
||||
initializeSamlSecuredWar("/saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader);
|
||||
initializeSamlSecuredWar("/saml/bad-realm-signed-post", "/bad-realm-sales-post-sig", "bad-realm-post-sig.war", classLoader);
|
||||
initializeSamlSecuredWar("/saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader);
|
||||
|
@ -79,9 +80,14 @@ public class SamlBindingTest {
|
|||
Thread.sleep(10000000);
|
||||
}
|
||||
|
||||
protected void checkLoggedOut() {
|
||||
Assert.assertTrue(driver.getPageSource().contains("request-path: /logout.jsp"));
|
||||
Assert.assertTrue(driver.getPageSource().contains("principal=null"));
|
||||
protected void checkLoggedOut(String mainUrl) {
|
||||
String pageSource = driver.getPageSource();
|
||||
System.out.println("*** logout pagesouce ***");
|
||||
System.out.println(pageSource);
|
||||
System.out.println("driver url: " + driver.getCurrentUrl());
|
||||
Assert.assertTrue(pageSource.contains("request-path: /logout.jsp"));
|
||||
driver.navigate().to(mainUrl);
|
||||
Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,7 +100,7 @@ public class SamlBindingTest {
|
|||
System.out.println(driver.getPageSource());
|
||||
Assert.assertTrue(driver.getPageSource().contains("bburke"));
|
||||
driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
|
||||
checkLoggedOut();
|
||||
checkLoggedOut("http://localhost:8081/sales-post/");
|
||||
}
|
||||
@Test
|
||||
public void testPostSignedLoginLogout() {
|
||||
|
@ -104,7 +110,7 @@ public class SamlBindingTest {
|
|||
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
|
||||
Assert.assertTrue(driver.getPageSource().contains("bburke"));
|
||||
driver.navigate().to("http://localhost:8081/sales-post-sig?GLO=true");
|
||||
checkLoggedOut();
|
||||
checkLoggedOut("http://localhost:8081/sales-post-sig/");
|
||||
|
||||
}
|
||||
@Test
|
||||
|
@ -117,7 +123,7 @@ public class SamlBindingTest {
|
|||
Assert.assertFalse(driver.getPageSource().contains("bburke"));
|
||||
Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
|
||||
driver.navigate().to("http://localhost:8081/sales-post-sig-transient?GLO=true");
|
||||
checkLoggedOut();
|
||||
checkLoggedOut("http://localhost:8081/sales-post-sig-transient/");
|
||||
|
||||
}
|
||||
@Test
|
||||
|
@ -130,7 +136,7 @@ public class SamlBindingTest {
|
|||
Assert.assertFalse(driver.getPageSource().contains("bburke"));
|
||||
Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
|
||||
driver.navigate().to("http://localhost:8081/sales-post-sig-persistent?GLO=true");
|
||||
checkLoggedOut();
|
||||
checkLoggedOut("http://localhost:8081/sales-post-sig-persistent/");
|
||||
|
||||
}
|
||||
@Test
|
||||
|
@ -142,7 +148,7 @@ public class SamlBindingTest {
|
|||
System.out.println(driver.getPageSource());
|
||||
Assert.assertTrue(driver.getPageSource().contains("principal=bburke@redhat.com"));
|
||||
driver.navigate().to("http://localhost:8081/sales-post-sig-email?GLO=true");
|
||||
checkLoggedOut();
|
||||
checkLoggedOut("http://localhost:8081/sales-post-sig-email/");
|
||||
|
||||
}
|
||||
@Test
|
||||
|
@ -153,7 +159,45 @@ public class SamlBindingTest {
|
|||
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
|
||||
Assert.assertTrue(driver.getPageSource().contains("bburke"));
|
||||
driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
|
||||
checkLoggedOut();
|
||||
checkLoggedOut("http://localhost:8081/employee-sig/");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRedirectSignedLoginLogoutFrontNoSSO() {
|
||||
driver.navigate().to("http://localhost:8081/employee-sig-front/");
|
||||
Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
|
||||
loginPage.login("bburke", "password");
|
||||
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
|
||||
Assert.assertTrue(driver.getPageSource().contains("bburke"));
|
||||
driver.navigate().to("http://localhost:8081/employee-sig-front?GLO=true");
|
||||
checkLoggedOut("http://localhost:8081/employee-sig-front/");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRedirectSignedLoginLogoutFront() {
|
||||
// visit 1st app an logg in
|
||||
System.out.println("visit 1st app ");
|
||||
driver.navigate().to("http://localhost:8081/employee-sig/");
|
||||
Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
|
||||
System.out.println("login to form");
|
||||
loginPage.login("bburke", "password");
|
||||
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
|
||||
Assert.assertTrue(driver.getPageSource().contains("bburke"));
|
||||
|
||||
// visit 2nd app
|
||||
System.out.println("visit 2nd app ");
|
||||
driver.navigate().to("http://localhost:8081/employee-sig-front/");
|
||||
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
|
||||
Assert.assertTrue(driver.getPageSource().contains("bburke"));
|
||||
|
||||
// logout of first app
|
||||
System.out.println("GLO");
|
||||
driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
|
||||
checkLoggedOut("http://localhost:8081/employee-sig/");
|
||||
driver.navigate().to("http://localhost:8081/employee-sig-front/");
|
||||
Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -165,7 +209,7 @@ public class SamlBindingTest {
|
|||
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-enc/");
|
||||
Assert.assertTrue(driver.getPageSource().contains("bburke"));
|
||||
driver.navigate().to("http://localhost:8081/sales-post-enc?GLO=true");
|
||||
checkLoggedOut();
|
||||
checkLoggedOut("http://localhost:8081/sales-post-enc/");
|
||||
|
||||
}
|
||||
@Test
|
||||
|
@ -213,7 +257,7 @@ public class SamlBindingTest {
|
|||
String pageSource = driver.getPageSource();
|
||||
Assert.assertTrue(pageSource.contains("bburke"));
|
||||
driver.navigate().to("http://localhost:8081/sales-metadata?GLO=true");
|
||||
checkLoggedOut();
|
||||
checkLoggedOut("http://localhost:8081/sales-metadata/");
|
||||
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,38 @@
|
|||
<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
|
||||
<PicketLinkSP xmlns="urn:picketlink:identity-federation:config:2.1"
|
||||
ServerEnvironment="tomcat" BindingType="REDIRECT" SupportsSignatures="true" LogOutResponseLocation="${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml}">
|
||||
<IdentityURL>${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml}
|
||||
</IdentityURL>
|
||||
<ServiceURL>${employee-sig.url::http://localhost:8081/employee-sig-front/}
|
||||
</ServiceURL>
|
||||
<KeyProvider
|
||||
ClassName="org.picketlink.identity.federation.core.impl.KeyStoreKeyManager">
|
||||
<Auth Key="KeyStoreURL" Value="saml/signed-front-get/WEB-INF/keystore.jks" />
|
||||
<Auth Key="KeyStorePass" Value="store123" />
|
||||
<Auth Key="SigningKeyPass" Value="test123" />
|
||||
<Auth Key="SigningKeyAlias" Value="http://localhost:8080/employee-sig/" />
|
||||
<ValidatingAlias Key="localhost" Value="demo" />
|
||||
<ValidatingAlias Key="127.0.0.1" Value="demo" />
|
||||
</KeyProvider>
|
||||
</PicketLinkSP>
|
||||
<Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
|
||||
<Handler
|
||||
class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
|
||||
<Handler
|
||||
class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler">
|
||||
<Option Key="NAMEID_FORMAT" Value="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>
|
||||
</Handler>
|
||||
<Handler
|
||||
class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
|
||||
<Handler
|
||||
class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureGenerationHandler">
|
||||
<!--
|
||||
This is a optional configuration. By default, method http://www.w3.org/2000/09/xmldsig#rsa-sha1
|
||||
and digest http://www.w3.org/2000/09/xmldsig#sha1 are used. -->
|
||||
<Option Key="SIGN_METHOD" Value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
|
||||
<Option Key="SIGN_DIGEST" Value="http://www.w3.org/2001/04/xmlenc#sha256"/>
|
||||
</Handler>
|
||||
<Handler
|
||||
class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler" />
|
||||
</Handlers>
|
||||
</PicketLink>
|
|
@ -194,6 +194,26 @@
|
|||
"saml.signing.private.key": "MIICXQIBAAKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABAoGANU1efgc6ojIvwn7Lsf8GAKN9z2D6uS0T3I9nw1k2CtI+xWhgKAUltEANx5lEfBRYIdYclidRpqrk8DYgzASrDYTHXzqVBJfAk1VrAGpqyRq+TNMLUHkXiTiSDOQ6WqhX93UGMmAgQm1RsLa6+fy1BO/B2y85+Yf2OUylsKS6avECQQDslRDiNFdtEjdvyOL20tQ7+W+eKVxVxKAyQ3gFjIIDizELZt+Jq1Wz6XV9NhK1JFtlVugeD1tlW/+K16fEmDYXAkEAzqKoN/JeGb20rfQldAUWdQbb0jrQAYlgoSU/9fYH9YVJT8vnkfhPBTwIw9H9euf1//lRP/jHltHd5ch4230YyQJBAN3rOkoltPiABPZbpuLGgwS7BwOCYrWlWmurtBLoaTCvyVKbrgXybNL1pBrOtR+rufvGWLeRyja65Gs1vY6BBQMCQQCTsNq/MjJj/522f7yNUl2cw4w2lOa7Um+IflFbAcDqkZu2ty0Kvgns2d4B6INeZ5ECpjaWnMA7YkFRzZnkd2NRAkB8lEY56ScnNigoZkkjtEUd2ejdhZPYuS9SKfv9zHwN+I+DE2vVFZz8GPq/iLcMx13PkZaYaJNQ4FtQY/hRLSn5",
|
||||
"saml.signing.certificate": "MIIB0DCCATkCBgFJH5u0EDANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNodHRwOi8vbG9jYWxob3N0OjgwODAvZW1wbG95ZWUtc2lnLzAeFw0xNDEwMTcxOTMzNThaFw0yNDEwMTcxOTM1MzhaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACKyPLGqMX8GsIrCfJU8eVnpaqzTXMglLVo/nTcfAnWe9UAdVe8N3a2PXpDBvuqNA/DEAhVcQgxdlOTWnB6s8/yLTRuH0bZgb3qGdySif+lU+E7zZ/SiDzavAvn+ABqemnzHcHyhYO+hNRGHvUbW5OAii9Vdjhm8BI32YF1NwhKp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "http://localhost:8081/employee-sig-front/",
|
||||
"enabled": true,
|
||||
"protocol": "saml",
|
||||
"fullScopeAllowed": true,
|
||||
"frontchannelLogout": true,
|
||||
"baseUrl": "http://localhost:8081/employee-sig-front",
|
||||
"adminUrl": "http://localhost:8081/employee-sig-front",
|
||||
"redirectUris": [
|
||||
"http://localhost:8081/employee-sig-front/*"
|
||||
],
|
||||
"attributes": {
|
||||
"saml.server.signature": "true",
|
||||
"saml.client.signature": "true",
|
||||
"saml.signature.algorithm": "RSA_SHA1",
|
||||
"saml.authnstatement": "true",
|
||||
"saml.signing.private.key": "MIICXQIBAAKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABAoGANU1efgc6ojIvwn7Lsf8GAKN9z2D6uS0T3I9nw1k2CtI+xWhgKAUltEANx5lEfBRYIdYclidRpqrk8DYgzASrDYTHXzqVBJfAk1VrAGpqyRq+TNMLUHkXiTiSDOQ6WqhX93UGMmAgQm1RsLa6+fy1BO/B2y85+Yf2OUylsKS6avECQQDslRDiNFdtEjdvyOL20tQ7+W+eKVxVxKAyQ3gFjIIDizELZt+Jq1Wz6XV9NhK1JFtlVugeD1tlW/+K16fEmDYXAkEAzqKoN/JeGb20rfQldAUWdQbb0jrQAYlgoSU/9fYH9YVJT8vnkfhPBTwIw9H9euf1//lRP/jHltHd5ch4230YyQJBAN3rOkoltPiABPZbpuLGgwS7BwOCYrWlWmurtBLoaTCvyVKbrgXybNL1pBrOtR+rufvGWLeRyja65Gs1vY6BBQMCQQCTsNq/MjJj/522f7yNUl2cw4w2lOa7Um+IflFbAcDqkZu2ty0Kvgns2d4B6INeZ5ECpjaWnMA7YkFRzZnkd2NRAkB8lEY56ScnNigoZkkjtEUd2ejdhZPYuS9SKfv9zHwN+I+DE2vVFZz8GPq/iLcMx13PkZaYaJNQ4FtQY/hRLSn5",
|
||||
"saml.signing.certificate": "MIIB0DCCATkCBgFJH5u0EDANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNodHRwOi8vbG9jYWxob3N0OjgwODAvZW1wbG95ZWUtc2lnLzAeFw0xNDEwMTcxOTMzNThaFw0yNDEwMTcxOTM1MzhaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACKyPLGqMX8GsIrCfJU8eVnpaqzTXMglLVo/nTcfAnWe9UAdVe8N3a2PXpDBvuqNA/DEAhVcQgxdlOTWnB6s8/yLTRuH0bZgb3qGdySif+lU+E7zZ/SiDzavAvn+ABqemnzHcHyhYO+hNRGHvUbW5OAii9Vdjhm8BI32YF1NwhKp"
|
||||
}
|
||||
}
|
||||
],
|
||||
"roles" : {
|
||||
|
|
Loading…
Reference in a new issue