more saml config
This commit is contained in:
parent
889fe8dd8c
commit
9b053e6918
8 changed files with 119 additions and 18 deletions
|
@ -96,12 +96,78 @@
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Force Name ID Format</term>
|
||||
<listitem>
|
||||
<para>
|
||||
If the request has a name ID policy, ignore it and used the value configured in the admin console
|
||||
under Name ID Format
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Name ID Format</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Name ID Format for the subject. If no name ID policy is specified in the request or if the
|
||||
Force Name ID Format attribute is true, this value is used.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Master SAML Processing URL</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This URL will be used for all SAML requests and responsed directed to the SP. It will be used
|
||||
as the Assertion Consumer Service URL and the Single Logout Service URL. If a login request
|
||||
contains the Assertion Consumer Service URL, that will take precedence, but this URL must be valided
|
||||
by a registered Valid Redirect URI pattern
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Assertion Consumer Service POST Binding URL</term>
|
||||
<listitem>
|
||||
<para>
|
||||
POST Binding URL for the Assertion Consumer Service.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Assertion Consumer Service Redirect Binding URL</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Redirect Binding URL for the Assertion Consumer Service.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Logout Service POST Binding URL</term>
|
||||
<listitem>
|
||||
<para>
|
||||
POST Binding URL for the Logout Service.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Logout Service Redirect Binding URL</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Redirect Binding URL for the Logout Service.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<para>
|
||||
You have to specify an admin URL if you want logout to work. This should be a URL that will except single logout
|
||||
requests from the Keycloak server. You should also specify a default redirect url. Keycloak will redirect to this
|
||||
url after single logout is complete.
|
||||
For login to work, Keycloak needs to be able to resolve the URL for the Assertion Consumer Service of the SP. If
|
||||
you are relying on the SP to provide this URL in the login request, then you must register valid redirect uri patterns
|
||||
so that this URL can be validated. You can set the Master SAML Processing URL as well, or alternatively, you can
|
||||
specify the Assertion Consumer Service URL per binding.
|
||||
</para>
|
||||
<para>
|
||||
For logout to work, you must specify a Master SAML Processing URL, or the Loging Service URL for the binding
|
||||
you want Keycloak to use.
|
||||
</para>
|
||||
<para>
|
||||
One thing to note is that roles are not treated as a hierarchy. So, any role mappings will just be added
|
||||
|
|
|
@ -221,16 +221,16 @@
|
|||
<fieldset>
|
||||
<legend collapsed><span class="text">Fine Grain SAML Endpoint Configuration</span> <span tooltip-placement="right" tooltip="Expand this section to configure exact URLs for Assertion Consumer and Single Logout Service." class="fa fa-info-circle"></span></legend>
|
||||
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
|
||||
<label class="col-sm-2 control-label" for="logoutPostBinding">Assertion Consumer Service POST Binding URL</label>
|
||||
<label class="col-sm-2 control-label" for="consumerServicePost">Assertion Consumer Service POST Binding URL</label>
|
||||
<div class="col-sm-6">
|
||||
<input ng-model="application.attributes.saml_assertion_consumer_service_url_post" class="form-control" type="text" name="logoutPostBinding" id="logoutPostBinding" />
|
||||
<input ng-model="application.attributes.saml_assertion_consumer_url_post" class="form-control" type="text" name="consumerServicePost" id="consumerServicePost" />
|
||||
</div>
|
||||
<span tooltip-placement="right" tooltip="SAML POST Binding URL for the application's assertion consumer service (login responses). You can leave this blank if you do not have a URL for this binding." class="fa fa-info-circle"></span>
|
||||
</div>
|
||||
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
|
||||
<label class="col-sm-2 control-label" for="logoutPostBinding">Assertion Consumer Service Redirect Binding URL</label>
|
||||
<label class="col-sm-2 control-label" for="consumerServiceRedirect">Assertion Consumer Service Redirect Binding URL</label>
|
||||
<div class="col-sm-6">
|
||||
<input ng-model="application.attributes.saml_assertion_consumer_service_url_redirect" class="form-control" type="text" name="logoutRedirectBinding" id="logoutRedirectBinding" />
|
||||
<input ng-model="application.attributes.saml_assertion_consumer_url_redirect" class="form-control" type="text" name="consumerServiceRedirect" id="consumerServiceRedirect" />
|
||||
</div>
|
||||
<span tooltip-placement="right" tooltip="SAML Redirect Binding URL for the application's assertion consumer service (login responses). You can leave this blank if you do not have a URL for this binding." class="fa fa-info-circle"></span>
|
||||
</div>
|
||||
|
|
|
@ -89,15 +89,20 @@ public class EntityDescriptorImporterService {
|
|||
if (spDescriptorType.isWantAssertionsSigned()) {
|
||||
app.setAttribute(SamlProtocol.SAML_ASSERTION_SIGNATURE, SamlProtocol.ATTRIBUTE_TRUE_VALUE);
|
||||
}
|
||||
String adminUrl = getLogoutLocation(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get());
|
||||
if (adminUrl != null) app.setManagementUrl(adminUrl);
|
||||
String logoutPost = getLogoutLocation(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get());
|
||||
if (logoutPost != null) app.setAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE, logoutPost);
|
||||
String logoutRedirect = getLogoutLocation(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get());
|
||||
if (logoutPost != null) app.setAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE, logoutRedirect);
|
||||
|
||||
String urlPattern = CoreConfigUtil.getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get());
|
||||
if (urlPattern == null) {
|
||||
urlPattern = CoreConfigUtil.getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get());
|
||||
String assertionConsumerServicePostBinding = CoreConfigUtil.getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get());
|
||||
if (assertionConsumerServicePostBinding != null) {
|
||||
app.setAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE, assertionConsumerServicePostBinding);
|
||||
app.addRedirectUri(assertionConsumerServicePostBinding);
|
||||
}
|
||||
if (urlPattern != null) {
|
||||
app.addRedirectUri(urlPattern);
|
||||
String assertionConsumerServiceRedirectBinding = CoreConfigUtil.getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get());
|
||||
if (assertionConsumerServiceRedirectBinding != null) {
|
||||
app.setAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE, assertionConsumerServiceRedirectBinding);
|
||||
app.addRedirectUri(assertionConsumerServiceRedirectBinding);
|
||||
}
|
||||
|
||||
for (KeyDescriptorType keyDescriptor : spDescriptorType.getKeyDescriptor()) {
|
||||
|
|
|
@ -51,6 +51,8 @@ public class SamlProtocol implements LoginProtocol {
|
|||
public static final String SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE = "saml_assertion_consumer_url_redirect";
|
||||
public static final String SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE = "saml_single_logout_service_url_post";
|
||||
public static final String SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE = "saml_single_logout_service_url_redirect";
|
||||
public static final String SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE = "saml_force_name_id_format";
|
||||
public static final String SAML_NAME_ID_FORMAT_ATTRIBUTE = "saml_name_id_format";
|
||||
public static final String LOGIN_PROTOCOL = "saml";
|
||||
public static final String SAML_BINDING = "saml_binding";
|
||||
public static final String SAML_POST_BINDING = "post";
|
||||
|
@ -175,10 +177,30 @@ public class SamlProtocol implements LoginProtocol {
|
|||
|
||||
protected String getNameIdFormat(ClientSessionModel clientSession) {
|
||||
String nameIdFormat = clientSession.getNote(GeneralConstants.NAMEID_FORMAT);
|
||||
ClientModel client = clientSession.getClient();
|
||||
boolean forceFormat = forceNameIdFormat(client);
|
||||
String configuredNameIdFormat = client.getAttribute(SAML_NAME_ID_FORMAT_ATTRIBUTE);
|
||||
if ((nameIdFormat == null || forceFormat) && configuredNameIdFormat != null) {
|
||||
if (configuredNameIdFormat.equals("email")) {
|
||||
nameIdFormat = JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get();
|
||||
} else if (configuredNameIdFormat.equals("persistent")) {
|
||||
nameIdFormat = JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get();
|
||||
} else if (configuredNameIdFormat.equals("transient")) {
|
||||
nameIdFormat = JBossSAMLURIConstants.NAMEID_FORMAT_TRANSIENT.get();
|
||||
} else if (configuredNameIdFormat.equals("username")) {
|
||||
nameIdFormat = JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get();
|
||||
} else {
|
||||
nameIdFormat = JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get();
|
||||
}
|
||||
}
|
||||
if(nameIdFormat == null) return SAML_DEFAULT_NAMEID_FORMAT;
|
||||
return nameIdFormat;
|
||||
}
|
||||
|
||||
public static boolean forceNameIdFormat(ClientModel client) {
|
||||
return "true".equals(client.getAttribute(SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE));
|
||||
}
|
||||
|
||||
protected String getNameId(String nameIdFormat, ClientSessionModel clientSession, UserSessionModel userSession) {
|
||||
if (nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get())) {
|
||||
return userSession.getUser().getEmail();
|
||||
|
|
|
@ -245,7 +245,7 @@ public class SamlService {
|
|||
|
||||
// Handle NameIDPolicy from SP
|
||||
NameIDPolicyType nameIdPolicy = requestAbstractType.getNameIDPolicy();
|
||||
if(nameIdPolicy != null) {
|
||||
if(nameIdPolicy != null && !SamlProtocol.forceNameIdFormat(client)) {
|
||||
String nameIdFormat = nameIdPolicy.getFormat().toString();
|
||||
// TODO: Handle AllowCreate too, relevant for persistent NameID.
|
||||
if(isSupportedNameIdFormat(nameIdFormat)) {
|
||||
|
@ -254,8 +254,6 @@ public class SamlService {
|
|||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unsupported NameIDFormat.");
|
||||
}
|
||||
} else {
|
||||
clientSession.setNote(GeneralConstants.NAMEID_FORMAT, JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get());
|
||||
}
|
||||
|
||||
Response response = authManager.checkNonFormAuthentication(session, clientSession, realm, uriInfo, request, clientConnection, headers, event);
|
||||
|
|
|
@ -24,6 +24,14 @@
|
|||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-dependencies-server-all</artifactId>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
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:emailAddress"/>
|
||||
<!-- <Option Key="NAMEID_FORMAT" Value="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/> -->
|
||||
</Handler>
|
||||
<Handler
|
||||
class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler"/>
|
||||
|
|
|
@ -123,6 +123,8 @@
|
|||
"http://localhost:8081/sales-post-sig-email/*"
|
||||
],
|
||||
"attributes": {
|
||||
"saml_force_name_id_format": "true",
|
||||
"saml_name_id_format": "email",
|
||||
"saml_assertion_consumer_url_post": "http://localhost:8081/sales-post-sig-email",
|
||||
"saml_assertion_consumer_url_redirect": "http://localhost:8081/sales-post-sig-email",
|
||||
"saml_single_logout_service_url_post": "http://localhost:8081/sales-post-sig-email",
|
||||
|
|
Loading…
Reference in a new issue