Merge pull request #3897 from anderius/feature/KEYCLOAK-4504-redirect-logout

[WIP] Saml broker: Option to specify logout request binding
This commit is contained in:
Bill Burke 2017-03-14 11:32:26 -04:00 committed by GitHub
commit 6d51862057
7 changed files with 39 additions and 9 deletions

View file

@ -303,7 +303,7 @@ public class SAMLEndpoint {
builder.issuer(issuerURL);
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder()
.relayState(relayState);
boolean postBinding = config.isPostBindingResponse();
boolean postBinding = config.isPostBindingLogout();
if (config.isWantAuthnRequestsSigned()) {
KeyManager.ActiveRsaKey keys = session.keys().getActiveRsaKey(realm);
String keyName = config.getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());

View file

@ -184,12 +184,15 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
try {
SAML2LogoutRequestBuilder logoutBuilder = buildLogoutRequest(userSession, uriInfo, realm, singleLogoutServiceUrl);
JaxrsSAML2BindingBuilder binding = buildLogoutBinding(session, userSession, realm);
return binding.postBinding(logoutBuilder.buildDocument()).request(singleLogoutServiceUrl);
if (getConfig().isPostBindingLogout()) {
return binding.postBinding(logoutBuilder.buildDocument()).request(singleLogoutServiceUrl);
} else {
return binding.redirectBinding(logoutBuilder.buildDocument()).request(singleLogoutServiceUrl);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
protected SAML2LogoutRequestBuilder buildLogoutRequest(UserSessionModel userSession, UriInfo uriInfo, RealmModel realm, String singleLogoutServiceUrl) {

View file

@ -161,6 +161,20 @@ public class SAMLIdentityProviderConfig extends IdentityProviderModel {
getConfig().put("postBindingResponse", String.valueOf(postBindingResponse));
}
public boolean isPostBindingLogout() {
String postBindingLogout = getConfig().get("postBindingLogout");
if (postBindingLogout == null) {
// To maintain unchanged behavior when adding this field, we set the inital value to equal that
// of the binding for the response:
return isPostBindingResponse();
}
return Boolean.valueOf(postBindingLogout);
}
public void setPostBindingLogout(boolean postBindingLogout) {
getConfig().put("postBindingLogout", String.valueOf(postBindingLogout));
}
public boolean isBackchannelSupported() {
return Boolean.valueOf(getConfig().get("backchannelSupported"));
}

View file

@ -84,11 +84,12 @@ public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory
if (idpDescriptor != null) {
SAMLIdentityProviderConfig samlIdentityProviderConfig = new SAMLIdentityProviderConfig();
String singleSignOnServiceUrl = null;
boolean postBinding = false;
boolean postBindingResponse = false;
boolean postBindingLogout = false;
for (EndpointType endpoint : idpDescriptor.getSingleSignOnService()) {
if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) {
singleSignOnServiceUrl = endpoint.getLocation().toString();
postBinding = true;
postBindingResponse = true;
break;
} else if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){
singleSignOnServiceUrl = endpoint.getLocation().toString();
@ -96,10 +97,11 @@ public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory
}
String singleLogoutServiceUrl = null;
for (EndpointType endpoint : idpDescriptor.getSingleLogoutService()) {
if (postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) {
if (postBindingResponse && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) {
singleLogoutServiceUrl = endpoint.getLocation().toString();
postBindingLogout = true;
break;
} else if (!postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){
} else if (!postBindingResponse && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){
singleLogoutServiceUrl = endpoint.getLocation().toString();
break;
}
@ -110,8 +112,9 @@ public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory
samlIdentityProviderConfig.setWantAuthnRequestsSigned(idpDescriptor.isWantAuthnRequestsSigned());
samlIdentityProviderConfig.setAddExtensionsElementWithKeyInfo(false);
samlIdentityProviderConfig.setValidateSignature(idpDescriptor.isWantAuthnRequestsSigned());
samlIdentityProviderConfig.setPostBindingResponse(postBinding);
samlIdentityProviderConfig.setPostBindingAuthnRequest(postBinding);
samlIdentityProviderConfig.setPostBindingResponse(postBindingResponse);
samlIdentityProviderConfig.setPostBindingAuthnRequest(postBindingResponse);
samlIdentityProviderConfig.setPostBindingLogout(postBindingLogout);
List<KeyDescriptorType> keyDescriptor = idpDescriptor.getKeyDescriptor();
String defaultCertificate = null;

View file

@ -536,6 +536,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
assertThat(config.keySet(), containsInAnyOrder(
"validateSignature",
"singleLogoutServiceUrl",
"postBindingLogout",
"postBindingResponse",
"postBindingAuthnRequest",
"singleSignOnServiceUrl",

View file

@ -531,6 +531,8 @@ http-post-binding-response=HTTP-POST Binding Response
http-post-binding-response.tooltip=Indicates whether to respond to requests using HTTP-POST binding. If false, HTTP-REDIRECT binding will be used.
http-post-binding-for-authn-request=HTTP-POST Binding for AuthnRequest
http-post-binding-for-authn-request.tooltip=Indicates whether the AuthnRequest must be sent using HTTP-POST binding. If false, HTTP-REDIRECT binding will be used.
http-post-binding-logout=HTTP-POST Binding Logout
http-post-binding-logout.tooltip=Indicates whether to respond to requests using HTTP-POST binding. If false, HTTP-REDIRECT binding will be used.
want-authn-requests-signed=Want AuthnRequests Signed
want-authn-requests-signed.tooltip=Indicates whether the identity provider expects signed a AuthnRequest.
force-authentication=Force Authentication

View file

@ -156,6 +156,13 @@
</div>
<kc-tooltip>{{:: 'http-post-binding-for-authn-request.tooltip' | translate}}</kc-tooltip>
</div>
<div class="form-group">
<label class="col-md-2 control-label" for="postBindingLogout">{{:: 'http-post-binding-logout' | translate}}</label>
<div class="col-md-6">
<input ng-model="identityProvider.config.postBindingLogout" id="postBindingLogout" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" />
</div>
<kc-tooltip>{{:: 'http-post-binding-logout.tooltip' | translate}}</kc-tooltip>
</div>
<div class="form-group">
<label class="col-md-2 control-label" for="wantAuthnRequestsSigned">{{:: 'want-authn-requests-signed' | translate}}</label>
<div class="col-md-6">