KEYCLOAK-4360: Add OneTimeUse condition to SAMLResponse
Add OneTimeUse Condition to SAMLResponse when configured in client settings
This commit is contained in:
parent
16d5ca3378
commit
c78c0b73d3
11 changed files with 217 additions and 60 deletions
|
@ -21,7 +21,9 @@ import org.keycloak.dom.saml.v2.assertion.AssertionType;
|
|||
import org.keycloak.dom.saml.v2.assertion.AudienceRestrictionType;
|
||||
import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
|
||||
import org.keycloak.dom.saml.v2.assertion.ConditionsType;
|
||||
import org.keycloak.dom.saml.v2.assertion.OneTimeUseType;
|
||||
import org.keycloak.dom.saml.v2.assertion.SubjectConfirmationDataType;
|
||||
import org.keycloak.dom.saml.v2.protocol.ExtensionsType;
|
||||
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
||||
import org.keycloak.saml.common.PicketLinkLogger;
|
||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
||||
|
@ -41,7 +43,6 @@ import org.w3c.dom.Document;
|
|||
import java.net.URI;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.keycloak.dom.saml.v2.protocol.ExtensionsType;
|
||||
|
||||
import static org.keycloak.saml.common.util.StringUtil.isNotNull;
|
||||
|
||||
|
@ -68,7 +69,7 @@ public class SAML2LoginResponseBuilder implements SamlProtocolExtensionsAwareBui
|
|||
protected String requestIssuer;
|
||||
protected String sessionIndex;
|
||||
protected final List<NodeGenerator> extensions = new LinkedList<>();
|
||||
|
||||
protected boolean includeOneTimeUseCondition;
|
||||
|
||||
public SAML2LoginResponseBuilder sessionIndex(String sessionIndex) {
|
||||
this.sessionIndex = sessionIndex;
|
||||
|
@ -140,6 +141,11 @@ public class SAML2LoginResponseBuilder implements SamlProtocolExtensionsAwareBui
|
|||
return this;
|
||||
}
|
||||
|
||||
public SAML2LoginResponseBuilder includeOneTimeUseCondition(boolean includeOneTimeUseCondition) {
|
||||
this.includeOneTimeUseCondition = includeOneTimeUseCondition;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SAML2LoginResponseBuilder addExtension(NodeGenerator extension) {
|
||||
this.extensions.add(extension);
|
||||
|
@ -217,6 +223,10 @@ public class SAML2LoginResponseBuilder implements SamlProtocolExtensionsAwareBui
|
|||
assertion.addStatement(authnStatement);
|
||||
}
|
||||
|
||||
if (includeOneTimeUseCondition) {
|
||||
assertion.getConditions().addCondition(new OneTimeUseType());
|
||||
}
|
||||
|
||||
if (!this.extensions.isEmpty()) {
|
||||
ExtensionsType extensionsType = new ExtensionsType();
|
||||
for (NodeGenerator extension : this.extensions) {
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.keycloak.dom.saml.v2.assertion.ConditionAbstractType;
|
|||
import org.keycloak.dom.saml.v2.assertion.ConditionsType;
|
||||
import org.keycloak.dom.saml.v2.assertion.EncryptedElementType;
|
||||
import org.keycloak.dom.saml.v2.assertion.NameIDType;
|
||||
import org.keycloak.dom.saml.v2.assertion.OneTimeUseType;
|
||||
import org.keycloak.dom.saml.v2.assertion.StatementAbstractType;
|
||||
import org.keycloak.dom.saml.v2.assertion.SubjectType;
|
||||
import org.keycloak.dom.saml.v2.assertion.URIType;
|
||||
|
@ -99,7 +100,8 @@ public class SAMLAssertionWriter extends BaseWriter {
|
|||
}
|
||||
|
||||
if (conditions.getNotOnOrAfter() != null) {
|
||||
StaxUtil.writeAttribute(writer, JBossSAMLConstants.NOT_ON_OR_AFTER.get(), conditions.getNotOnOrAfter().toString());
|
||||
StaxUtil.writeAttribute(writer, JBossSAMLConstants.NOT_ON_OR_AFTER.get(),
|
||||
conditions.getNotOnOrAfter().toString());
|
||||
}
|
||||
|
||||
List<ConditionAbstractType> typeOfConditions = conditions.getConditions();
|
||||
|
@ -121,6 +123,11 @@ public class SAMLAssertionWriter extends BaseWriter {
|
|||
|
||||
StaxUtil.writeEndElement(writer);
|
||||
}
|
||||
if (typeCondition instanceof OneTimeUseType) {
|
||||
StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.ONE_TIME_USE.get(),
|
||||
ASSERTION_NSURI.get());
|
||||
StaxUtil.writeEndElement(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,8 +244,8 @@ public class SAMLAssertionWriter extends BaseWriter {
|
|||
if (uriTypes != null) {
|
||||
for (URIType uriType : uriTypes) {
|
||||
if (uriType instanceof AuthnContextDeclType) {
|
||||
StaxUtil.writeStartElement(writer, ASSERTION_PREFIX,
|
||||
JBossSAMLConstants.AUTHN_CONTEXT_DECLARATION.get(), ASSERTION_NSURI.get());
|
||||
StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.AUTHN_CONTEXT_DECLARATION.get(),
|
||||
ASSERTION_NSURI.get());
|
||||
StaxUtil.writeCharacters(writer, uriType.getValue().toASCIIString());
|
||||
StaxUtil.writeEndElement(writer);
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ public class SamlClient extends ClientConfigResolver {
|
|||
return "true".equals(resolveAttribute(SamlConfigAttributes.SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE));
|
||||
|
||||
}
|
||||
|
||||
public void setForceNameIDFormat(boolean val) {
|
||||
client.setAttribute(SamlConfigAttributes.SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE, Boolean.toString(val));
|
||||
}
|
||||
|
@ -139,6 +140,7 @@ public class SamlClient extends ClientConfigResolver {
|
|||
client.setAttribute(SamlConfigAttributes.SAML_FORCE_POST_BINDING, Boolean.toString(val));
|
||||
|
||||
}
|
||||
|
||||
public boolean requiresAssertionSignature() {
|
||||
return "true".equals(resolveAttribute(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE));
|
||||
}
|
||||
|
@ -147,6 +149,7 @@ public class SamlClient extends ClientConfigResolver {
|
|||
client.setAttribute(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE, Boolean.toString(val));
|
||||
|
||||
}
|
||||
|
||||
public boolean requiresEncryption() {
|
||||
return "true".equals(resolveAttribute(SamlConfigAttributes.SAML_ENCRYPT));
|
||||
}
|
||||
|
@ -192,6 +195,7 @@ public class SamlClient extends ClientConfigResolver {
|
|||
client.setAttribute(SamlConfigAttributes.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE, val);
|
||||
|
||||
}
|
||||
|
||||
public String getClientEncryptingPrivateKey() {
|
||||
return client.getAttribute(SamlConfigAttributes.SAML_ENCRYPTION_PRIVATE_KEY_ATTRIBUTE);
|
||||
}
|
||||
|
@ -203,6 +207,7 @@ public class SamlClient extends ClientConfigResolver {
|
|||
|
||||
/**
|
||||
* Always returns non-{@code null} result.
|
||||
*
|
||||
* @return Configured ransformer of {@link #DEFAULT_XML_KEY_INFO_KEY_NAME_TRANSFORMER} if not set.
|
||||
*/
|
||||
public XmlKeyInfoKeyNameTransformer getXmlSigKeyInfoKeyNameTransformer() {
|
||||
|
@ -218,4 +223,13 @@ public class SamlClient extends ClientConfigResolver {
|
|||
: xmlSigKeyInfoKeyNameTransformer.name());
|
||||
}
|
||||
|
||||
public boolean includeOneTimeUseCondition() {
|
||||
return "true".equals(resolveAttribute(SamlConfigAttributes.SAML_ONETIMEUSE_CONDITION));
|
||||
}
|
||||
|
||||
public void setIncludeOneTimeUseCondition(boolean val) {
|
||||
client.setAttribute(SamlConfigAttributes.SAML_ONETIMEUSE_CONDITION, Boolean.toString(val));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public interface SamlConfigAttributes {
|
|||
String SAML_SIGNATURE_ALGORITHM = "saml.signature.algorithm";
|
||||
String SAML_NAME_ID_FORMAT_ATTRIBUTE = "saml_name_id_format";
|
||||
String SAML_AUTHNSTATEMENT = "saml.authnstatement";
|
||||
String SAML_ONETIMEUSE_CONDITION = "saml.onetimeuse.condition";
|
||||
String SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE = "saml_force_name_id_format";
|
||||
String SAML_SERVER_SIGNATURE = "saml.server.signature";
|
||||
String SAML_SERVER_SIGNATURE_KEYINFO_EXT = "saml.server.signature.keyinfo.ext";
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
|
|||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.keycloak.connections.httpclient.HttpClientProvider;
|
||||
import org.keycloak.dom.saml.v2.assertion.AssertionType;
|
||||
import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
|
||||
|
@ -56,12 +55,12 @@ 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.common.util.XmlKeyInfoKeyNameTransformer;
|
||||
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
|
||||
import org.keycloak.services.ErrorPage;
|
||||
import org.keycloak.services.managers.ClientSessionCode;
|
||||
import org.keycloak.services.managers.ResourceAdminManager;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
@ -81,8 +80,6 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
@ -382,6 +379,8 @@ public class SamlProtocol implements LoginProtocol {
|
|||
builder.disableAuthnStatement(true);
|
||||
}
|
||||
|
||||
builder.includeOneTimeUseCondition(samlClient.includeOneTimeUseCondition());
|
||||
|
||||
List<ProtocolMapperProcessor<SAMLAttributeStatementMapper>> attributeStatementMappers = new LinkedList<>();
|
||||
List<ProtocolMapperProcessor<SAMLLoginResponseMapper>> loginResponseMappers = new LinkedList<>();
|
||||
ProtocolMapperProcessor<SAMLRoleListMapper> roleListMapper = null;
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.testsuite.saml;
|
||||
|
||||
import com.google.common.collect.Collections2;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.ClientsResource;
|
||||
import org.keycloak.dom.saml.v2.assertion.ConditionAbstractType;
|
||||
import org.keycloak.dom.saml.v2.assertion.ConditionsType;
|
||||
import org.keycloak.dom.saml.v2.assertion.OneTimeUseType;
|
||||
import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
|
||||
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
||||
import org.keycloak.protocol.saml.SamlConfigAttributes;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
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.api.saml.v2.request.SAML2Request;
|
||||
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
|
||||
import org.keycloak.testsuite.util.SamlClient;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.keycloak.testsuite.util.SamlClient.login;
|
||||
|
||||
/**
|
||||
* KEYCLOAK-4360
|
||||
* @author mrpardijs
|
||||
*/
|
||||
public class IncludeOneTimeUseConditionTest extends AbstractSamlTest
|
||||
{
|
||||
@Test
|
||||
public void testOneTimeUseConditionIsAdded() throws Exception
|
||||
{
|
||||
testOneTimeUseConditionIncluded(Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneTimeUseConditionIsNotAdded() throws Exception
|
||||
{
|
||||
testOneTimeUseConditionIncluded(Boolean.FALSE);
|
||||
}
|
||||
|
||||
private void testOneTimeUseConditionIncluded(Boolean oneTimeUseConditionShouldBeIncluded) throws ProcessingException, ConfigurationException, ParsingException
|
||||
{
|
||||
ClientsResource clients = adminClient.realm(REALM_NAME).clients();
|
||||
List<ClientRepresentation> foundClients = clients.findByClientId(SAML_CLIENT_ID_SALES_POST);
|
||||
assertThat(foundClients, hasSize(1));
|
||||
ClientResource clientRes = clients.get(foundClients.get(0).getId());
|
||||
ClientRepresentation client = clientRes.toRepresentation();
|
||||
client.getAttributes().put(SamlConfigAttributes.SAML_ONETIMEUSE_CONDITION, oneTimeUseConditionShouldBeIncluded.toString());
|
||||
clientRes.update(client);
|
||||
|
||||
AuthnRequestType loginRep = createLoginRequestDocument(SAML_CLIENT_ID_SALES_POST, SAML_ASSERTION_CONSUMER_URL_SALES_POST, REALM_NAME);
|
||||
loginRep.setProtocolBinding(SamlClient.Binding.POST.getBindingUri());
|
||||
|
||||
Document samlRequest = SAML2Request.convert(loginRep);
|
||||
SAMLDocumentHolder res = login(bburkeUser, getAuthServerSamlEndpoint(REALM_NAME), samlRequest, null, SamlClient.Binding.POST,
|
||||
SamlClient.Binding.POST);
|
||||
|
||||
assertThat(res.getSamlObject(), notNullValue());
|
||||
assertThat(res.getSamlObject(), instanceOf(ResponseType.class));
|
||||
|
||||
ResponseType rt = (ResponseType) res.getSamlObject();
|
||||
assertThat(rt.getAssertions(), not(empty()));
|
||||
final ConditionsType conditionsType = rt.getAssertions().get(0).getAssertion().getConditions();
|
||||
assertThat(conditionsType, notNullValue());
|
||||
assertThat(conditionsType.getConditions(), not(empty()));
|
||||
|
||||
final List<ConditionAbstractType> conditions = conditionsType.getConditions();
|
||||
|
||||
final Collection<ConditionAbstractType> oneTimeUseConditions = Collections2.filter(conditions, input -> input instanceof OneTimeUseType);
|
||||
|
||||
final boolean oneTimeUseConditionAdded = !oneTimeUseConditions.isEmpty();
|
||||
assertThat(oneTimeUseConditionAdded, is(oneTimeUseConditionShouldBeIncluded));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
package org.keycloak.testsuite.console.page.clients.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.testsuite.console.page.clients.CreateClientForm;
|
||||
import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
|
||||
|
@ -9,10 +13,6 @@ import org.openqa.selenium.WebElement;
|
|||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.ui.Select;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.keycloak.testsuite.util.WaitUtils.pause;
|
||||
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
|
||||
|
||||
|
@ -68,9 +68,7 @@ public class ClientSettingsForm extends CreateClientForm {
|
|||
private List<WebElement> deleteWebOriginIcons;
|
||||
|
||||
public enum OidcAccessType {
|
||||
BEARER_ONLY("bearer-only"),
|
||||
PUBLIC("public"),
|
||||
CONFIDENTIAL("confidential");
|
||||
BEARER_ONLY("bearer-only"), PUBLIC("public"), CONFIDENTIAL("confidential");
|
||||
|
||||
private final String name;
|
||||
|
||||
|
@ -218,6 +216,7 @@ public class ClientSettingsForm extends CreateClientForm {
|
|||
|
||||
public static final String SAML_ASSERTION_SIGNATURE = "saml.assertion.signature";
|
||||
public static final String SAML_AUTHNSTATEMENT = "saml.authnstatement";
|
||||
public static final String SAML_ONETIMEUSE_CONDITION = "saml.onetimeuse.condition";
|
||||
public static final String SAML_CLIENT_SIGNATURE = "saml.client.signature";
|
||||
public static final String SAML_ENCRYPT = "saml.encrypt";
|
||||
public static final String SAML_FORCE_POST_BINDING = "saml.force.post.binding";
|
||||
|
@ -235,6 +234,8 @@ public class ClientSettingsForm extends CreateClientForm {
|
|||
|
||||
@FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlAuthnStatement']]")
|
||||
private OnOffSwitch samlAuthnStatement;
|
||||
@FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlOneTimeUseCondition']]")
|
||||
private OnOffSwitch samlOneTimeUseCondition;
|
||||
@FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlServerSignature']]")
|
||||
private OnOffSwitch samlServerSignature;
|
||||
@FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlServerSignatureEnableKeyInfoExtension']]")
|
||||
|
@ -275,6 +276,7 @@ public class ClientSettingsForm extends CreateClientForm {
|
|||
|
||||
Map<String, String> attributes = client.getAttributes();
|
||||
samlAuthnStatement.setOn("true".equals(attributes.get(SAML_AUTHNSTATEMENT)));
|
||||
samlOneTimeUseCondition.setOn("true".equals(attributes.get(SAML_ONETIMEUSE_CONDITION)));
|
||||
samlServerSignature.setOn("true".equals(attributes.get(SAML_SERVER_SIGNATURE)));
|
||||
samlAssertionSignature.setOn("true".equals(attributes.get(SAML_ASSERTION_SIGNATURE)));
|
||||
if (samlServerSignature.isOn() || samlAssertionSignature.isOn()) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import static org.keycloak.testsuite.console.page.clients.settings.ClientSetting
|
|||
import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_FORCE_NAME_ID_FORMAT;
|
||||
import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_FORCE_POST_BINDING;
|
||||
import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_NAME_ID_FORMAT;
|
||||
import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_ONETIMEUSE_CONDITION;
|
||||
import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_SERVER_SIGNATURE;
|
||||
import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_SIGNATURE_ALGORITHM;
|
||||
import static org.keycloak.testsuite.util.AttributesAssert.assertEqualsBooleanAttributes;
|
||||
|
@ -86,6 +87,7 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
|
|||
attributes.put(SAML_SIGNATURE_ALGORITHM, "RSA_SHA256");
|
||||
attributes.put(SAML_FORCE_NAME_ID_FORMAT, "false");
|
||||
attributes.put(SAML_NAME_ID_FORMAT, "username");
|
||||
attributes.put(SAML_ONETIMEUSE_CONDITION, "true");
|
||||
return attributes;
|
||||
}
|
||||
|
||||
|
@ -128,7 +130,8 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
|
|||
|
||||
public ProtocolMapperRepresentation findClientMapperByName(String clientId, String mapperName) {
|
||||
ProtocolMapperRepresentation found = null;
|
||||
for (ProtocolMapperRepresentation mapper : testRealmResource().clients().get(clientId).getProtocolMappers().getMappers()) {
|
||||
for (ProtocolMapperRepresentation mapper : testRealmResource().clients().get(clientId).getProtocolMappers()
|
||||
.getMappers()) {
|
||||
if (mapperName.equals(mapper.getName())) {
|
||||
found = mapper;
|
||||
}
|
||||
|
|
|
@ -226,6 +226,8 @@ service-accounts-enabled=Service Accounts Enabled
|
|||
service-accounts-enabled.tooltip=Allows you to authenticate this client to Keycloak and retrieve access token dedicated to this client. In terms of OAuth2 specification, this enables support of 'Client Credentials Grant' for this client.
|
||||
include-authnstatement=Include AuthnStatement
|
||||
include-authnstatement.tooltip=Should a statement specifying the method and timestamp be included in login responses?
|
||||
include-onetimeuse-condition=Include OneTimeUse Condition
|
||||
include-onetimeuse-condition.tooltip=Should a OneTimeUse Condition be included in login responses?
|
||||
sign-documents=Sign Documents
|
||||
sign-documents.tooltip=Should SAML documents be signed by the realm?
|
||||
sign-documents-redirect-enable-key-info-ext=Optimize REDIRECT signing key lookup
|
||||
|
|
|
@ -863,6 +863,7 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, templates,
|
|||
|
||||
$scope.realm = realm;
|
||||
$scope.samlAuthnStatement = false;
|
||||
$scope.samlOneTimeUseCondition = false;
|
||||
$scope.samlMultiValuedRoles = false;
|
||||
$scope.samlServerSignature = false;
|
||||
$scope.samlServerSignatureEnableKeyInfoExtension = false;
|
||||
|
@ -959,6 +960,13 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, templates,
|
|||
$scope.samlAuthnStatement = false;
|
||||
}
|
||||
}
|
||||
if ($scope.client.attributes["saml.onetimeuse.condition"]) {
|
||||
if ($scope.client.attributes["saml.onetimeuse.condition"] == "true") {
|
||||
$scope.samlOneTimeUseCondition = true;
|
||||
} else {
|
||||
$scope.samlOneTimeUseCondition = false;
|
||||
}
|
||||
}
|
||||
if ($scope.client.attributes["saml_force_name_id_format"]) {
|
||||
if ($scope.client.attributes["saml_force_name_id_format"] == "true") {
|
||||
$scope.samlForceNameIdFormat = true;
|
||||
|
@ -1177,6 +1185,12 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, templates,
|
|||
$scope.clientEdit.attributes["saml.authnstatement"] = "false";
|
||||
|
||||
}
|
||||
if ($scope.samlOneTimeUseCondition == true) {
|
||||
$scope.clientEdit.attributes["saml.onetimeuse.condition"] = "true";
|
||||
} else {
|
||||
$scope.clientEdit.attributes["saml.onetimeuse.condition"] = "false";
|
||||
|
||||
}
|
||||
if ($scope.samlForceNameIdFormat == true) {
|
||||
$scope.clientEdit.attributes["saml_force_name_id_format"] = "true";
|
||||
} else {
|
||||
|
|
|
@ -124,6 +124,13 @@
|
|||
</div>
|
||||
<kc-tooltip>{{:: 'include-authnstatement.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
|
||||
<label class="col-md-2 control-label" for="samlOneTimeUseCondition">{{:: 'include-onetimeuse-condition' | translate}}</label>
|
||||
<div class="col-sm-6">
|
||||
<input ng-model="samlOneTimeUseCondition" ng-click="switchChange()" name="samlOneTimeUseCondition" id="samlOneTimeUseCondition" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'include-onetimeuse-condition.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
|
||||
<label class="col-md-2 control-label" for="samlServerSignature">{{:: 'sign-documents' | translate}}</label>
|
||||
<div class="col-sm-6">
|
||||
|
|
Loading…
Reference in a new issue