saml adapter schema and simplifications
This commit is contained in:
parent
8acdaf462b
commit
d06237a3fd
18 changed files with 318 additions and 92 deletions
|
@ -210,7 +210,6 @@ public class DefaultSamlDeployment implements SamlDeployment {
|
||||||
private KeyPair signingKeyPair;
|
private KeyPair signingKeyPair;
|
||||||
private String assertionConsumerServiceUrl;
|
private String assertionConsumerServiceUrl;
|
||||||
private Set<String> roleAttributeNames;
|
private Set<String> roleAttributeNames;
|
||||||
private Set<String> roleFriendlyAttributeNames;
|
|
||||||
private PrincipalNamePolicy principalNamePolicy = PrincipalNamePolicy.FROM_NAME_ID;
|
private PrincipalNamePolicy principalNamePolicy = PrincipalNamePolicy.FROM_NAME_ID;
|
||||||
private String principalAttributeName;
|
private String principalAttributeName;
|
||||||
private String logoutPage;
|
private String logoutPage;
|
||||||
|
@ -268,11 +267,6 @@ public class DefaultSamlDeployment implements SamlDeployment {
|
||||||
return roleAttributeNames;
|
return roleAttributeNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getRoleAttributeFriendlyNames() {
|
|
||||||
return roleFriendlyAttributeNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrincipalNamePolicy getPrincipalNamePolicy() {
|
public PrincipalNamePolicy getPrincipalNamePolicy() {
|
||||||
return principalNamePolicy;
|
return principalNamePolicy;
|
||||||
|
@ -323,10 +317,6 @@ public class DefaultSamlDeployment implements SamlDeployment {
|
||||||
this.roleAttributeNames = roleAttributeNames;
|
this.roleAttributeNames = roleAttributeNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoleFriendlyAttributeNames(Set<String> roleFriendlyAttributeNames) {
|
|
||||||
this.roleFriendlyAttributeNames = roleFriendlyAttributeNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrincipalNamePolicy(PrincipalNamePolicy principalNamePolicy) {
|
public void setPrincipalNamePolicy(PrincipalNamePolicy principalNamePolicy) {
|
||||||
this.principalNamePolicy = principalNamePolicy;
|
this.principalNamePolicy = principalNamePolicy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -354,7 +354,7 @@ public abstract class SamlAuthenticator {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isRole(AttributeType attribute) {
|
protected boolean isRole(AttributeType attribute) {
|
||||||
return deployment.getRoleAttributeNames().contains(attribute.getName()) || deployment.getRoleAttributeFriendlyNames().contains(attribute.getFriendlyName());
|
return (attribute.getName() != null && deployment.getRoleAttributeNames().contains(attribute.getName())) || (attribute.getFriendlyName() != null && deployment.getRoleAttributeNames().contains(attribute.getFriendlyName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AuthOutcome handleLogoutResponse(SAMLDocumentHolder holder, StatusResponseType responseType, String relayState) {
|
protected AuthOutcome handleLogoutResponse(SAMLDocumentHolder holder, StatusResponseType responseType, String relayState) {
|
||||||
|
|
|
@ -64,7 +64,6 @@ public interface SamlDeployment {
|
||||||
String getLogoutPage();
|
String getLogoutPage();
|
||||||
|
|
||||||
Set<String> getRoleAttributeNames();
|
Set<String> getRoleAttributeNames();
|
||||||
Set<String> getRoleAttributeFriendlyNames();
|
|
||||||
|
|
||||||
enum PrincipalNamePolicy {
|
enum PrincipalNamePolicy {
|
||||||
FROM_NAME_ID,
|
FROM_NAME_ID,
|
||||||
|
|
|
@ -134,6 +134,8 @@ public class IDP implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String entityID;
|
private String entityID;
|
||||||
|
private String signatureAlgorithm;
|
||||||
|
private String signatureCanonicalizationMethod;
|
||||||
private SingleSignOnService singleSignOnService;
|
private SingleSignOnService singleSignOnService;
|
||||||
private SingleLogoutService singleLogoutService;
|
private SingleLogoutService singleLogoutService;
|
||||||
private List<Key> keys;
|
private List<Key> keys;
|
||||||
|
@ -169,4 +171,21 @@ public class IDP implements Serializable {
|
||||||
public void setKeys(List<Key> keys) {
|
public void setKeys(List<Key> keys) {
|
||||||
this.keys = keys;
|
this.keys = keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSignatureAlgorithm() {
|
||||||
|
return signatureAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignatureAlgorithm(String signatureAlgorithm) {
|
||||||
|
this.signatureAlgorithm = signatureAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSignatureCanonicalizationMethod() {
|
||||||
|
return signatureCanonicalizationMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignatureCanonicalizationMethod(String signatureCanonicalizationMethod) {
|
||||||
|
this.signatureCanonicalizationMethod = signatureCanonicalizationMethod;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,9 +41,6 @@ public class SP implements Serializable {
|
||||||
private String nameIDPolicyFormat;
|
private String nameIDPolicyFormat;
|
||||||
private PrincipalNameMapping principalNameMapping;
|
private PrincipalNameMapping principalNameMapping;
|
||||||
private Set<String> roleAttributes;
|
private Set<String> roleAttributes;
|
||||||
private Set<String> roleFriendlyAttributes;
|
|
||||||
private String signatureAlgorithm;
|
|
||||||
private String signatureCanonicalizationMethod;
|
|
||||||
private IDP idp;
|
private IDP idp;
|
||||||
|
|
||||||
public String getEntityID() {
|
public String getEntityID() {
|
||||||
|
@ -102,14 +99,6 @@ public class SP implements Serializable {
|
||||||
this.roleAttributes = roleAttributes;
|
this.roleAttributes = roleAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getRoleFriendlyAttributes() {
|
|
||||||
return roleFriendlyAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoleFriendlyAttributes(Set<String> roleFriendlyAttributes) {
|
|
||||||
this.roleFriendlyAttributes = roleFriendlyAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDP getIdp() {
|
public IDP getIdp() {
|
||||||
return idp;
|
return idp;
|
||||||
}
|
}
|
||||||
|
@ -126,19 +115,4 @@ public class SP implements Serializable {
|
||||||
this.logoutPage = logoutPage;
|
this.logoutPage = logoutPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSignatureAlgorithm() {
|
|
||||||
return signatureAlgorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSignatureAlgorithm(String signatureAlgorithm) {
|
|
||||||
this.signatureAlgorithm = signatureAlgorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignatureCanonicalizationMethod() {
|
|
||||||
return signatureCanonicalizationMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSignatureCanonicalizationMethod(String signatureCanonicalizationMethod) {
|
|
||||||
this.signatureCanonicalizationMethod = signatureCanonicalizationMethod;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,10 @@ public class ConfigXmlConstants {
|
||||||
|
|
||||||
public static final String ROLE_MAPPING_ELEMENT = "RoleMapping";
|
public static final String ROLE_MAPPING_ELEMENT = "RoleMapping";
|
||||||
public static final String ATTRIBUTE_ELEMENT = "Attribute";
|
public static final String ATTRIBUTE_ELEMENT = "Attribute";
|
||||||
public static final String FRIENDLY_ATTRIBUTE_ELEMENT = "FriendlyAttribute";
|
|
||||||
public static final String NAME_ATTR = "name";
|
public static final String NAME_ATTR = "name";
|
||||||
|
|
||||||
public static final String IDP_ELEMENT = "IDP";
|
public static final String IDP_ELEMENT = "IDP";
|
||||||
|
public static final String SIGNATURES_REQUIRED_ATTR = "signaturesRequired";
|
||||||
public static final String SINGLE_SIGN_ON_SERVICE_ELEMENT = "SingleSignOnService";
|
public static final String SINGLE_SIGN_ON_SERVICE_ELEMENT = "SingleSignOnService";
|
||||||
public static final String SINGLE_LOGOUT_SERVICE_ELEMENT = "SingleLogoutService";
|
public static final String SINGLE_LOGOUT_SERVICE_ELEMENT = "SingleLogoutService";
|
||||||
public static final String SIGN_REQUEST_ATTR = "signRequest";
|
public static final String SIGN_REQUEST_ATTR = "signRequest";
|
||||||
|
|
|
@ -41,10 +41,10 @@ public class DeploymentBuilder {
|
||||||
deployment.setForceAuthentication(sp.isForceAuthentication());
|
deployment.setForceAuthentication(sp.isForceAuthentication());
|
||||||
deployment.setNameIDPolicyFormat(sp.getNameIDPolicyFormat());
|
deployment.setNameIDPolicyFormat(sp.getNameIDPolicyFormat());
|
||||||
deployment.setLogoutPage(sp.getLogoutPage());
|
deployment.setLogoutPage(sp.getLogoutPage());
|
||||||
deployment.setSignatureCanonicalizationMethod(sp.getSignatureCanonicalizationMethod());
|
deployment.setSignatureCanonicalizationMethod(sp.getIdp().getSignatureCanonicalizationMethod());
|
||||||
deployment.setSignatureAlgorithm(SignatureAlgorithm.RSA_SHA256);
|
deployment.setSignatureAlgorithm(SignatureAlgorithm.RSA_SHA256);
|
||||||
if (sp.getSignatureAlgorithm() != null) {
|
if (sp.getIdp().getSignatureAlgorithm() != null) {
|
||||||
deployment.setSignatureAlgorithm(SignatureAlgorithm.valueOf(sp.getSignatureAlgorithm()));
|
deployment.setSignatureAlgorithm(SignatureAlgorithm.valueOf(sp.getIdp().getSignatureAlgorithm()));
|
||||||
}
|
}
|
||||||
if (sp.getPrincipalNameMapping() != null) {
|
if (sp.getPrincipalNameMapping() != null) {
|
||||||
SamlDeployment.PrincipalNamePolicy policy = SamlDeployment.PrincipalNamePolicy.valueOf(sp.getPrincipalNameMapping().getPolicy());
|
SamlDeployment.PrincipalNamePolicy policy = SamlDeployment.PrincipalNamePolicy.valueOf(sp.getPrincipalNameMapping().getPolicy());
|
||||||
|
@ -52,7 +52,6 @@ public class DeploymentBuilder {
|
||||||
deployment.setPrincipalAttributeName(sp.getPrincipalNameMapping().getAttributeName());
|
deployment.setPrincipalAttributeName(sp.getPrincipalNameMapping().getAttributeName());
|
||||||
}
|
}
|
||||||
deployment.setRoleAttributeNames(sp.getRoleAttributes());
|
deployment.setRoleAttributeNames(sp.getRoleAttributes());
|
||||||
deployment.setRoleFriendlyAttributeNames(sp.getRoleFriendlyAttributes());
|
|
||||||
if (sp.getSslPolicy() != null) {
|
if (sp.getSslPolicy() != null) {
|
||||||
SslRequired ssl = SslRequired.valueOf(sp.getSslPolicy());
|
SslRequired ssl = SslRequired.valueOf(sp.getSslPolicy());
|
||||||
deployment.setSslRequired(ssl);
|
deployment.setSslRequired(ssl);
|
||||||
|
|
|
@ -30,6 +30,10 @@ public class IDPXmlParser extends AbstractParser {
|
||||||
|
|
||||||
}
|
}
|
||||||
idp.setEntityID(entityID);
|
idp.setEntityID(entityID);
|
||||||
|
|
||||||
|
boolean signaturesRequired = StaxParserUtil.getBooleanAttributeValue(startElement, ConfigXmlConstants.SIGNATURES_REQUIRED_ATTR);
|
||||||
|
idp.setSignatureCanonicalizationMethod(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SIGNATURE_CANONICALIZATION_METHOD_ATTR));
|
||||||
|
idp.setSignatureAlgorithm(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SIGNATURE_ALGORITHM_ATTR));
|
||||||
while (xmlEventReader.hasNext()) {
|
while (xmlEventReader.hasNext()) {
|
||||||
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
|
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
|
||||||
if (xmlEvent == null)
|
if (xmlEvent == null)
|
||||||
|
@ -47,11 +51,11 @@ public class IDPXmlParser extends AbstractParser {
|
||||||
break;
|
break;
|
||||||
String tag = StaxParserUtil.getStartElementName(startElement);
|
String tag = StaxParserUtil.getStartElementName(startElement);
|
||||||
if (tag.equals(ConfigXmlConstants.SINGLE_SIGN_ON_SERVICE_ELEMENT)) {
|
if (tag.equals(ConfigXmlConstants.SINGLE_SIGN_ON_SERVICE_ELEMENT)) {
|
||||||
IDP.SingleSignOnService sso = parseSingleSignOnService(xmlEventReader);
|
IDP.SingleSignOnService sso = parseSingleSignOnService(xmlEventReader, signaturesRequired);
|
||||||
idp.setSingleSignOnService(sso);
|
idp.setSingleSignOnService(sso);
|
||||||
|
|
||||||
} else if (tag.equals(ConfigXmlConstants.SINGLE_LOGOUT_SERVICE_ELEMENT)) {
|
} else if (tag.equals(ConfigXmlConstants.SINGLE_LOGOUT_SERVICE_ELEMENT)) {
|
||||||
IDP.SingleLogoutService slo = parseSingleLogoutService(xmlEventReader);
|
IDP.SingleLogoutService slo = parseSingleLogoutService(xmlEventReader, signaturesRequired);
|
||||||
idp.setSingleLogoutService(slo);
|
idp.setSingleLogoutService(slo);
|
||||||
|
|
||||||
} else if (tag.equals(ConfigXmlConstants.KEYS_ELEMENT)) {
|
} else if (tag.equals(ConfigXmlConstants.KEYS_ELEMENT)) {
|
||||||
|
@ -66,25 +70,25 @@ public class IDPXmlParser extends AbstractParser {
|
||||||
return idp;
|
return idp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IDP.SingleLogoutService parseSingleLogoutService(XMLEventReader xmlEventReader) throws ParsingException {
|
protected IDP.SingleLogoutService parseSingleLogoutService(XMLEventReader xmlEventReader, boolean signaturesRequired) throws ParsingException {
|
||||||
IDP.SingleLogoutService slo = new IDP.SingleLogoutService();
|
IDP.SingleLogoutService slo = new IDP.SingleLogoutService();
|
||||||
StartElement element = StaxParserUtil.getNextStartElement(xmlEventReader);
|
StartElement element = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
slo.setSignRequest(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_REQUEST_ATTR));
|
slo.setSignRequest(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_REQUEST_ATTR, signaturesRequired));
|
||||||
slo.setValidateResponseSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_RESPONSE_SIGNATURE_ATTR));
|
slo.setValidateResponseSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_RESPONSE_SIGNATURE_ATTR, signaturesRequired));
|
||||||
slo.setValidateRequestSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_REQUEST_SIGNATURE_ATTR));
|
slo.setValidateRequestSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_REQUEST_SIGNATURE_ATTR, signaturesRequired));
|
||||||
slo.setRequestBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.REQUEST_BINDING_ATTR));
|
slo.setRequestBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.REQUEST_BINDING_ATTR));
|
||||||
slo.setResponseBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.RESPONSE_BINDING_ATTR));
|
slo.setResponseBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.RESPONSE_BINDING_ATTR));
|
||||||
slo.setSignResponse(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_RESPONSE_ATTR));
|
slo.setSignResponse(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_RESPONSE_ATTR, signaturesRequired));
|
||||||
slo.setPostBindingUrl(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.POST_BINDING_URL_ATTR));
|
slo.setPostBindingUrl(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.POST_BINDING_URL_ATTR));
|
||||||
slo.setRedirectBindingUrl(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.REDIRECT_BINDING_URL_ATTR));
|
slo.setRedirectBindingUrl(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.REDIRECT_BINDING_URL_ATTR));
|
||||||
return slo;
|
return slo;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IDP.SingleSignOnService parseSingleSignOnService(XMLEventReader xmlEventReader) throws ParsingException {
|
protected IDP.SingleSignOnService parseSingleSignOnService(XMLEventReader xmlEventReader, boolean signaturesRequired) throws ParsingException {
|
||||||
IDP.SingleSignOnService sso = new IDP.SingleSignOnService();
|
IDP.SingleSignOnService sso = new IDP.SingleSignOnService();
|
||||||
StartElement element = StaxParserUtil.getNextStartElement(xmlEventReader);
|
StartElement element = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
sso.setSignRequest(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_REQUEST_ATTR));
|
sso.setSignRequest(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_REQUEST_ATTR, signaturesRequired));
|
||||||
sso.setValidateResponseSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_RESPONSE_SIGNATURE_ATTR));
|
sso.setValidateResponseSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_RESPONSE_SIGNATURE_ATTR, signaturesRequired));
|
||||||
sso.setRequestBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.REQUEST_BINDING_ATTR));
|
sso.setRequestBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.REQUEST_BINDING_ATTR));
|
||||||
sso.setResponseBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.RESPONSE_BINDING_ATTR));
|
sso.setResponseBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.RESPONSE_BINDING_ATTR));
|
||||||
sso.setBindingUrl(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.BINDING_URL_ATTR));
|
sso.setBindingUrl(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.BINDING_URL_ATTR));
|
||||||
|
|
|
@ -7,6 +7,8 @@ import org.keycloak.saml.common.util.StaxParserUtil;
|
||||||
|
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import javax.xml.stream.events.Characters;
|
||||||
import javax.xml.stream.events.EndElement;
|
import javax.xml.stream.events.EndElement;
|
||||||
import javax.xml.stream.events.StartElement;
|
import javax.xml.stream.events.StartElement;
|
||||||
import javax.xml.stream.events.XMLEvent;
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
|
|
@ -37,8 +37,6 @@ public class SPXmlParser extends AbstractParser {
|
||||||
sp.setSslPolicy(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SSL_POLICY_ATTR));
|
sp.setSslPolicy(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SSL_POLICY_ATTR));
|
||||||
sp.setLogoutPage(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.LOGOUT_PAGE_ATTR));
|
sp.setLogoutPage(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.LOGOUT_PAGE_ATTR));
|
||||||
sp.setNameIDPolicyFormat(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.NAME_ID_POLICY_FORMAT_ATTR));
|
sp.setNameIDPolicyFormat(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.NAME_ID_POLICY_FORMAT_ATTR));
|
||||||
sp.setSignatureCanonicalizationMethod(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SIGNATURE_CANONICALIZATION_METHOD_ATTR));
|
|
||||||
sp.setSignatureAlgorithm(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SIGNATURE_ALGORITHM_ATTR));
|
|
||||||
sp.setForceAuthentication(StaxParserUtil.getBooleanAttributeValue(startElement, ConfigXmlConstants.FORCE_AUTHENTICATION_ATTR));
|
sp.setForceAuthentication(StaxParserUtil.getBooleanAttributeValue(startElement, ConfigXmlConstants.FORCE_AUTHENTICATION_ATTR));
|
||||||
while (xmlEventReader.hasNext()) {
|
while (xmlEventReader.hasNext()) {
|
||||||
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
|
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
|
||||||
|
@ -91,7 +89,6 @@ public class SPXmlParser extends AbstractParser {
|
||||||
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
StaxParserUtil.validate(startElement, ConfigXmlConstants.ROLE_MAPPING_ELEMENT);
|
StaxParserUtil.validate(startElement, ConfigXmlConstants.ROLE_MAPPING_ELEMENT);
|
||||||
Set<String> roleAttributes = new HashSet<>();
|
Set<String> roleAttributes = new HashSet<>();
|
||||||
Set<String> roleFriendlyAttributes = new HashSet<>();
|
|
||||||
while (xmlEventReader.hasNext()) {
|
while (xmlEventReader.hasNext()) {
|
||||||
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
|
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
|
||||||
if (xmlEvent == null)
|
if (xmlEvent == null)
|
||||||
|
@ -116,21 +113,12 @@ public class SPXmlParser extends AbstractParser {
|
||||||
|
|
||||||
}
|
}
|
||||||
roleAttributes.add(attributeValue);
|
roleAttributes.add(attributeValue);
|
||||||
} else if (tag.equals(ConfigXmlConstants.FRIENDLY_ATTRIBUTE_ELEMENT)) {
|
|
||||||
StartElement element = StaxParserUtil.getNextStartElement(xmlEventReader);
|
|
||||||
String attributeValue = StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.NAME_ATTR);
|
|
||||||
if (attributeValue == null) {
|
|
||||||
throw new ParsingException("RoleMapping FriendlyAttribute element must have the name attribute set");
|
|
||||||
|
|
||||||
}
|
|
||||||
roleFriendlyAttributes.add(attributeValue);
|
|
||||||
} else {
|
} else {
|
||||||
StaxParserUtil.bypassElementBlock(xmlEventReader, tag);
|
StaxParserUtil.bypassElementBlock(xmlEventReader, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
sp.setRoleAttributes(roleAttributes);
|
sp.setRoleAttributes(roleAttributes);
|
||||||
sp.setRoleFriendlyAttributes(roleFriendlyAttributes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
115
saml/client-adapter/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd
Executable file
115
saml/client-adapter/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd
Executable file
|
@ -0,0 +1,115 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<xs:schema version="1.0"
|
||||||
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns="urn:keycloak:saml:adapter"
|
||||||
|
targetNamespace="urn:keycloak:saml:adapter"
|
||||||
|
elementFormDefault="qualified"
|
||||||
|
attributeFormDefault="unqualified">
|
||||||
|
|
||||||
|
<xs:element name="keycloak-saml-adapter" type="adapter-type"/>
|
||||||
|
<xs:complexType name="adapter-type">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>
|
||||||
|
<![CDATA[
|
||||||
|
The Keycloak SAML Adapter keycloak-saml.xml config file
|
||||||
|
]]>
|
||||||
|
</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="SP" maxOccurs="1" minOccurs="0" type="sp-type"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="sp-type">
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Keys" type="keys-type" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="PrincipalNameMapping" type="principal-name-mapping-type" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="RoleMapping" type="role-mapping-type" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="IDP" type="idp-type" minOccurs="1" maxOccurs="1"/>
|
||||||
|
</xs:all>
|
||||||
|
<xs:attribute name="entityID" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="sslPolicy" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="nameIDPolicyFormat" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="logoutPage" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="forceAuthentication" type="xs:boolean" use="optional"/>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="keys-type">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="Key" type="key-type" minOccurs="1" maxOccurs="2"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="key-type">
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="KeyStore" maxOccurs="1" minOccurs="0" type="key-store-type"/>
|
||||||
|
<xs:element name="PrivateKeyPem" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="PublicKeyPem" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="CertificatePem" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||||
|
</xs:all>
|
||||||
|
<xs:attribute name="signing" type="xs:boolean" use="optional"/>
|
||||||
|
<xs:attribute name="encryption" type="xs:boolean" use="optional"/>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="key-store-type">
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="PrivateKey" maxOccurs="1" minOccurs="0" type="private-key-type"/>
|
||||||
|
<xs:element name="Certificate" type="certificate-type" minOccurs="0" maxOccurs="1"/>
|
||||||
|
</xs:all>
|
||||||
|
<xs:attribute name="file" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="resource" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="password" type="xs:string" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="private-key-type">
|
||||||
|
<xs:attribute name="alias" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="password" type="xs:string" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="certificate-type">
|
||||||
|
<xs:attribute name="alias" type="xs:string" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="principal-name-mapping-type">
|
||||||
|
<xs:attribute name="policy" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="attribute" type="xs:string" use="optional"/>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="role-mapping-type">
|
||||||
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="Attribute" maxOccurs="unbounded" minOccurs="0" type="attribute-type"/>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="attribute-type">
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="idp-type">
|
||||||
|
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="SingleSignOnService" maxOccurs="1" minOccurs="1" type="sign-on-type"/>
|
||||||
|
<xs:element name="SingleLogoutService" type="logout-type" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="Keys" type="keys-type" minOccurs="0" maxOccurs="1"/>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="entityID" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="signaturesRequired" type="xs:boolean" use="required"/>
|
||||||
|
<xs:attribute name="signatureAlgorithm" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="signatureCanonicalizationMethod" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="encryption" type="xs:boolean" use="optional"/>
|
||||||
|
</xs:complexType>
|
||||||
|
<xs:complexType name="sign-on-type">
|
||||||
|
<xs:attribute name="signRequest" type="xs:boolean" use="optional"/>
|
||||||
|
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional"/>
|
||||||
|
<xs:attribute name="requestBinding" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="responseBinding" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="bindingUrl" type="xs:string" use="optional"/>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="logout-type">
|
||||||
|
<xs:attribute name="signRequest" type="xs:boolean" use="optional"/>
|
||||||
|
<xs:attribute name="signResponse" type="xs:boolean" use="optional"/>
|
||||||
|
<xs:attribute name="validateRequestSignature" type="xs:boolean" use="optional"/>
|
||||||
|
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional"/>
|
||||||
|
<xs:attribute name="requestBinding" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="responseBinding" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="postBindingUrl" type="xs:string" use="optional"/>
|
||||||
|
<xs:attribute name="redirectBindingUrl" type="xs:string" use="optional"/>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</xs:schema>
|
|
@ -7,7 +7,15 @@ import org.keycloak.adapters.saml.config.Key;
|
||||||
import org.keycloak.adapters.saml.config.KeycloakSamlAdapter;
|
import org.keycloak.adapters.saml.config.KeycloakSamlAdapter;
|
||||||
import org.keycloak.adapters.saml.config.SP;
|
import org.keycloak.adapters.saml.config.SP;
|
||||||
import org.keycloak.adapters.saml.config.parsers.KeycloakSamlAdapterXMLParser;
|
import org.keycloak.adapters.saml.config.parsers.KeycloakSamlAdapterXMLParser;
|
||||||
|
import org.keycloak.saml.common.util.StaxParserUtil;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
import javax.xml.transform.stax.StAXSource;
|
||||||
|
import javax.xml.transform.stream.StreamSource;
|
||||||
|
import javax.xml.validation.Schema;
|
||||||
|
import javax.xml.validation.SchemaFactory;
|
||||||
|
import javax.xml.validation.Validator;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +24,37 @@ import java.io.InputStream;
|
||||||
*/
|
*/
|
||||||
public class XmlParserTest {
|
public class XmlParserTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidation() throws Exception {
|
||||||
|
{
|
||||||
|
InputStream schema = KeycloakSamlAdapterXMLParser.class.getResourceAsStream("/schema/keycloak_saml_adapter_1_6.xsd");
|
||||||
|
InputStream is = getClass().getResourceAsStream("/keycloak-saml.xml");
|
||||||
|
Assert.assertNotNull(is);
|
||||||
|
Assert.assertNotNull(schema);
|
||||||
|
StaxParserUtil.validate(is, schema);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
InputStream sch = KeycloakSamlAdapterXMLParser.class.getResourceAsStream("/schema/keycloak_saml_adapter_1_6.xsd");
|
||||||
|
InputStream doc = getClass().getResourceAsStream("/keycloak-saml2.xml");
|
||||||
|
Assert.assertNotNull(doc);
|
||||||
|
Assert.assertNotNull(sch);
|
||||||
|
try {
|
||||||
|
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||||
|
Schema schema = factory.newSchema(new StreamSource(sch));
|
||||||
|
Validator validator = schema.newValidator();
|
||||||
|
StreamSource source = new StreamSource(doc);
|
||||||
|
source.setSystemId("/keycloak-saml2.xml");
|
||||||
|
validator.validate(source);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testXmlParser() throws Exception {
|
public void testXmlParser() throws Exception {
|
||||||
InputStream is = getClass().getResourceAsStream("/keycloak-saml.xml");
|
InputStream is = getClass().getResourceAsStream("/keycloak-saml.xml");
|
||||||
|
@ -48,11 +87,11 @@ public class XmlParserTest {
|
||||||
Assert.assertEquals("attribute", sp.getPrincipalNameMapping().getAttributeName());
|
Assert.assertEquals("attribute", sp.getPrincipalNameMapping().getAttributeName());
|
||||||
Assert.assertTrue(sp.getRoleAttributes().size() == 1);
|
Assert.assertTrue(sp.getRoleAttributes().size() == 1);
|
||||||
Assert.assertTrue(sp.getRoleAttributes().contains("member"));
|
Assert.assertTrue(sp.getRoleAttributes().contains("member"));
|
||||||
Assert.assertTrue(sp.getRoleFriendlyAttributes().size() == 1);
|
|
||||||
Assert.assertTrue(sp.getRoleFriendlyAttributes().contains("memberOf"));
|
|
||||||
|
|
||||||
IDP idp = sp.getIdp();
|
IDP idp = sp.getIdp();
|
||||||
Assert.assertEquals("idp", idp.getEntityID());
|
Assert.assertEquals("idp", idp.getEntityID());
|
||||||
|
Assert.assertEquals("RSA", idp.getSignatureAlgorithm());
|
||||||
|
Assert.assertEquals("canon", idp.getSignatureCanonicalizationMethod());
|
||||||
Assert.assertTrue(idp.getSingleSignOnService().isSignRequest());
|
Assert.assertTrue(idp.getSingleSignOnService().isSignRequest());
|
||||||
Assert.assertTrue(idp.getSingleSignOnService().isValidateResponseSignature());
|
Assert.assertTrue(idp.getSingleSignOnService().isValidateResponseSignature());
|
||||||
Assert.assertEquals("post", idp.getSingleSignOnService().getRequestBinding());
|
Assert.assertEquals("post", idp.getSingleSignOnService().getRequestBinding());
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<keycloak-saml-adapter>
|
<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter">
|
||||||
<SP entityID="sp"
|
<SP entityID="sp"
|
||||||
sslPolicy="ssl"
|
sslPolicy="ssl"
|
||||||
nameIDPolicyFormat="format"
|
nameIDPolicyFormat="format"
|
||||||
signatureAlgorithm=""
|
|
||||||
sgnatureCanonicalizationMethod=""
|
|
||||||
forceAuthentication="true">
|
forceAuthentication="true">
|
||||||
<Keys>
|
<Keys>
|
||||||
<Key signing="true" >
|
<Key signing="true" >
|
||||||
|
@ -24,9 +22,12 @@
|
||||||
<PrincipalNameMapping policy="policy" attribute="attribute"/>
|
<PrincipalNameMapping policy="policy" attribute="attribute"/>
|
||||||
<RoleMapping>
|
<RoleMapping>
|
||||||
<Attribute name="member"/>
|
<Attribute name="member"/>
|
||||||
<FriendlyAttribute name="memberOf"/>
|
|
||||||
</RoleMapping>
|
</RoleMapping>
|
||||||
<IDP entityID="idp">
|
<IDP entityID="idp"
|
||||||
|
signatureAlgorithm="RSA"
|
||||||
|
signatureCanonicalizationMethod="canon"
|
||||||
|
signaturesRequired="true"
|
||||||
|
>
|
||||||
<SingleSignOnService signRequest="true"
|
<SingleSignOnService signRequest="true"
|
||||||
validateResponseSignature="true"
|
validateResponseSignature="true"
|
||||||
requestBinding="post"
|
requestBinding="post"
|
||||||
|
|
46
saml/client-adapter/core/src/test/resources/keycloak-saml2.xml
Executable file
46
saml/client-adapter/core/src/test/resources/keycloak-saml2.xml
Executable file
|
@ -0,0 +1,46 @@
|
||||||
|
<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter">
|
||||||
|
<SP entityID="sp"
|
||||||
|
sslPolicy="ssl"
|
||||||
|
nameIDPolicyFormat="format"
|
||||||
|
signatureAlgorithm=""
|
||||||
|
signatureCanonicalizationMethod=""
|
||||||
|
forceAuthentication="true">
|
||||||
|
<Keys>
|
||||||
|
<Key signing="true" >
|
||||||
|
<KeyStore file="file" resource="cp" password="pw">
|
||||||
|
<PrivateKey alias="private alias" password="private pw"/>
|
||||||
|
<Certificate alias="cert alias"/>
|
||||||
|
</KeyStore>
|
||||||
|
</Key>
|
||||||
|
<Key encryption="true">
|
||||||
|
<PrivateKeyPemmm>
|
||||||
|
private pem
|
||||||
|
</PrivateKeyPemmm>
|
||||||
|
<PublicKeyPem>
|
||||||
|
public pem
|
||||||
|
</PublicKeyPem>
|
||||||
|
</Key>
|
||||||
|
</Keys>
|
||||||
|
<PrincipalNameMapping policy="policy" attribute="attribute"/>
|
||||||
|
<RoleMapping>
|
||||||
|
<Attribute name="member"/>
|
||||||
|
</RoleMapping>
|
||||||
|
<IDP entityID="idp"
|
||||||
|
signaturesRequired="true"
|
||||||
|
>
|
||||||
|
<SingleSignOnService signRequest="true"
|
||||||
|
validateResponseSignature="true"
|
||||||
|
requestBinding="post"
|
||||||
|
bindingUrl="url"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Keys>
|
||||||
|
<Key signing="true">
|
||||||
|
<CertificatePem>
|
||||||
|
cert pem
|
||||||
|
</CertificatePem>
|
||||||
|
</Key>
|
||||||
|
</Keys>
|
||||||
|
</IDP>
|
||||||
|
</SP>
|
||||||
|
</keycloak-saml-adapter>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Template used by WildFly build when directed to include Keycloak subsystem in a configuration. -->
|
||||||
|
<config>
|
||||||
|
<extension-module>org.keycloak.keycloak-saml-adapter-subsystem</extension-module>
|
||||||
|
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.6">
|
||||||
|
</subsystem>
|
||||||
|
</config>
|
|
@ -27,13 +27,16 @@ import org.keycloak.saml.common.exceptions.ParsingException;
|
||||||
import org.keycloak.saml.common.ErrorCodes;
|
import org.keycloak.saml.common.ErrorCodes;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
import javax.xml.stream.Location;
|
import javax.xml.stream.Location;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
import javax.xml.stream.XMLInputFactory;
|
import javax.xml.stream.XMLInputFactory;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.events.Attribute;
|
import javax.xml.stream.events.Attribute;
|
||||||
|
import javax.xml.stream.events.Characters;
|
||||||
import javax.xml.stream.events.EndElement;
|
import javax.xml.stream.events.EndElement;
|
||||||
import javax.xml.stream.events.StartElement;
|
import javax.xml.stream.events.StartElement;
|
||||||
import javax.xml.stream.events.XMLEvent;
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
@ -41,7 +44,11 @@ import javax.xml.transform.Source;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
import javax.xml.transform.dom.DOMResult;
|
import javax.xml.transform.dom.DOMResult;
|
||||||
import javax.xml.transform.stax.StAXSource;
|
import javax.xml.transform.stax.StAXSource;
|
||||||
|
import javax.xml.transform.stream.StreamSource;
|
||||||
|
import javax.xml.validation.Schema;
|
||||||
|
import javax.xml.validation.SchemaFactory;
|
||||||
import javax.xml.validation.Validator;
|
import javax.xml.validation.Validator;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +61,18 @@ public class StaxParserUtil {
|
||||||
|
|
||||||
private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
|
private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
|
||||||
|
|
||||||
protected static Validator validator = null;
|
public static void validate(InputStream doc, InputStream sch) throws ParsingException {
|
||||||
|
try {
|
||||||
|
XMLEventReader xmlEventReader = StaxParserUtil.getXMLEventReader(doc);
|
||||||
|
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||||
|
Schema schema = factory.newSchema(new StreamSource(sch));
|
||||||
|
Validator validator = schema.newValidator();
|
||||||
|
validator.validate(new StAXSource(xmlEventReader));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw logger.parserException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bypass an entire XML element block from startElement to endElement
|
* Bypass an entire XML element block from startElement to endElement
|
||||||
|
@ -75,6 +93,29 @@ public class StaxParserUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advances reader if character whitespace encountered
|
||||||
|
*
|
||||||
|
* @param xmlEventReader
|
||||||
|
* @param xmlEvent
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean wasWhitespacePeeked(XMLEventReader xmlEventReader, XMLEvent xmlEvent) {
|
||||||
|
if (xmlEvent.isCharacters()) {
|
||||||
|
Characters chars = xmlEvent.asCharacters();
|
||||||
|
String data = chars.getData();
|
||||||
|
if (data == null || data.trim().equals("")) {
|
||||||
|
try {
|
||||||
|
xmlEventReader.nextEvent();
|
||||||
|
return true;
|
||||||
|
} catch (XMLStreamException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an {@code Attribute}, get its trimmed value
|
* Given an {@code Attribute}, get its trimmed value
|
||||||
*
|
*
|
||||||
|
@ -113,11 +154,23 @@ public class StaxParserUtil {
|
||||||
* @return false if attribute not set
|
* @return false if attribute not set
|
||||||
*/
|
*/
|
||||||
public static boolean getBooleanAttributeValue(StartElement startElement, String tag) {
|
public static boolean getBooleanAttributeValue(StartElement startElement, String tag) {
|
||||||
|
return getBooleanAttributeValue(startElement, tag, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Attribute value
|
||||||
|
*
|
||||||
|
* @param startElement
|
||||||
|
* @param tag localpart of the qname of the attribute
|
||||||
|
*
|
||||||
|
* @return false if attribute not set
|
||||||
|
*/
|
||||||
|
public static boolean getBooleanAttributeValue(StartElement startElement, String tag, boolean defaultValue) {
|
||||||
String result = null;
|
String result = null;
|
||||||
Attribute attr = startElement.getAttributeByName(new QName(tag));
|
Attribute attr = startElement.getAttributeByName(new QName(tag));
|
||||||
if (attr != null)
|
if (attr != null)
|
||||||
result = getAttributeValue(attr);
|
result = getAttributeValue(attr);
|
||||||
if (result == null) return false;
|
if (result == null) return defaultValue;
|
||||||
return Boolean.valueOf(result);
|
return Boolean.valueOf(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,18 +16,13 @@
|
||||||
<RoleMapping>
|
<RoleMapping>
|
||||||
<Attribute name="Role"/>
|
<Attribute name="Role"/>
|
||||||
</RoleMapping>
|
</RoleMapping>
|
||||||
<IDP entityID="idp">
|
<IDP entityID="idp"
|
||||||
<SingleSignOnService signRequest="true"
|
signaturesRequired="true">
|
||||||
validateResponseSignature="true"
|
<SingleSignOnService requestBinding="POST"
|
||||||
requestBinding="POST"
|
|
||||||
bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
|
bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SingleLogoutService
|
<SingleLogoutService
|
||||||
validateRequestSignature="true"
|
|
||||||
validateResponseSignature="true"
|
|
||||||
signRequest="true"
|
|
||||||
signResponse="true"
|
|
||||||
requestBinding="POST"
|
requestBinding="POST"
|
||||||
responseBinding="POST"
|
responseBinding="POST"
|
||||||
postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
|
postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
|
||||||
|
|
|
@ -16,18 +16,13 @@
|
||||||
<RoleMapping>
|
<RoleMapping>
|
||||||
<Attribute name="Role"/>
|
<Attribute name="Role"/>
|
||||||
</RoleMapping>
|
</RoleMapping>
|
||||||
<IDP entityID="idp">
|
<IDP entityID="idp"
|
||||||
<SingleSignOnService signRequest="true"
|
signaturesRequired="true">
|
||||||
validateResponseSignature="true"
|
<SingleSignOnService requestBinding="POST"
|
||||||
requestBinding="POST"
|
|
||||||
bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
|
bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SingleLogoutService
|
<SingleLogoutService
|
||||||
validateRequestSignature="true"
|
|
||||||
validateResponseSignature="true"
|
|
||||||
signRequest="true"
|
|
||||||
signResponse="true"
|
|
||||||
requestBinding="POST"
|
requestBinding="POST"
|
||||||
responseBinding="POST"
|
responseBinding="POST"
|
||||||
postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
|
postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
|
||||||
|
|
Loading…
Reference in a new issue