[java-oidc-common] branch main updated: JCOMOIDC-51 - Support OIDC logout URIs in SAML metadata
Henri Mikkonen
henri.mikkonen at iki.fi
Fri Nov 4 08:29:59 UTC 2022
This is an automated email from the git hooks/post-receive script.
hjmikkon pushed a commit to branch main
in repository java-oidc-common.
View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=2dfe3ebe5f6a0f2ab208f23f38dfda88fa36cd34
The following commit(s) were added to refs/heads/main by this push:
new 2dfe3eb JCOMOIDC-51 - Support OIDC logout URIs in SAML metadata
2dfe3eb is described below
commit 2dfe3ebe5f6a0f2ab208f23f38dfda88fa36cd34
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Nov 4 10:26:28 2022 +0200
JCOMOIDC-51 - Support OIDC logout URIs in SAML metadata
https://shibboleth.atlassian.net/browse/JCOMOIDC-51
Add support for setting front-/back-channel logout URIs via
<SingleLogoutService> -elements. The binding refers to the corresponding
specification:
- https://openid.net/specs/openid-connect-frontchannel-1_0.html
- https://openid.net/specs/openid-connect-backchannel-1_0.html
OAuthRPExtensions now supports two new attributes (flags):
- frontchannel_logout_session_required
- backchannel_logout_session_required
---
.../impl/ClientInformationNodeProcessor.java | 47 +++++++
.../impl/ClientInformationNodeProcessorTest.java | 30 ++++-
.../impl/EntitiesDescriptor-with-oidcmd-logout.xml | 136 +++++++++++++++++++++
.../oidc/saml/xmlobject/OAuthRPExtensions.java | 46 ++++++-
.../resources/schema/saml-metadata-ext-oidcmd.xsd | 2 +
.../saml/xmlobject/impl/OAuthRPExtensionsImpl.java | 25 ++++
.../impl/OAuthRPExtensionsMarshaller.java | 10 ++
.../impl/OAuthRPExtensionsUnmarshaller.java | 8 ++
.../saml/xmlobject/impl/OAuthRPExtensionsTest.java | 6 +
.../oidc/saml/xmlobject/impl/OAuthRPExtensions.xml | 4 +-
.../xmlobject/impl/OAuthRPExtensions_ordered.xml | 4 +-
11 files changed, 314 insertions(+), 4 deletions(-)
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/ClientInformationNodeProcessor.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/ClientInformationNodeProcessor.java
index 9a55c2d..462dd34 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/ClientInformationNodeProcessor.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/ClientInformationNodeProcessor.java
@@ -42,6 +42,7 @@ import org.opensaml.saml.saml2.metadata.Extensions;
import org.opensaml.saml.saml2.metadata.NameIDFormat;
import org.opensaml.saml.saml2.metadata.RoleDescriptor;
import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml.saml2.metadata.SingleLogoutService;
import org.opensaml.saml.security.impl.MetadataCredentialResolver;
import org.opensaml.security.credential.Credential;
import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver;
@@ -92,6 +93,14 @@ public class ClientInformationNodeProcessor implements MetadataNodeProcessor {
/** The ACS binding identifier matching to the redirect_uri. */
public static final String BINDING_ID_REDIRECT_URI = "https://tools.ietf.org/html/rfc6749#section-3.1.2";
+ /** The SLO binding identifier matching to the front-channel uri. */
+ public static final String BINDING_ID_FRONT_SLO_URI =
+ "https://openid.net/specs/openid-connect-frontchannel-1_0.html";
+
+ /** The SLO binding identifier matching to the back-channel uri. */
+ public static final String BINDING_ID_BACK_SLO_URI =
+ "https://openid.net/specs/openid-connect-backchannel-1_0.html";
+
/** Class logger. */
private final Logger log = LoggerFactory.getLogger(ClientInformationNodeProcessor.class);
@@ -217,6 +226,22 @@ public class ClientInformationNodeProcessor implements MetadataNodeProcessor {
metadata.setJWKSet(parseJwkSet(credentials, clientId));
}
metadata.setCustomField("audience", parseAudiences(extensions));
+ final Set<URI> backChannelLogoutUris = parseLogoutUris(roleDescriptor, BINDING_ID_BACK_SLO_URI);
+ if (!backChannelLogoutUris.isEmpty()) {
+ if (backChannelLogoutUris.size() > 1) {
+ log.warn("More than one back-channel logout URI defined, picking up only one.");
+ }
+ metadata.setBackChannelLogoutURI(backChannelLogoutUris.iterator().next());
+ metadata.requiresBackChannelLogoutSession(extensions.isBackChannelLogoutSessionRequired());
+ }
+ final Set<URI> frontChannelLogoutUris = parseLogoutUris(roleDescriptor, BINDING_ID_FRONT_SLO_URI);
+ if (!frontChannelLogoutUris.isEmpty()) {
+ if (frontChannelLogoutUris.size() > 1) {
+ log.warn("More than one front-channel logout URI defined, picking up only one.");
+ }
+ metadata.setFrontChannelLogoutURI(frontChannelLogoutUris.iterator().next());
+ metadata.requiresFrontChannelLogoutSession(extensions.isFrontChannelLogoutSessionRequired());
+ }
} else {
log.debug("No {} found to be processed", OAuthRPExtensions.TYPE_LOCAL_NAME);
}
@@ -546,6 +571,28 @@ public class ClientInformationNodeProcessor implements MetadataNodeProcessor {
return auds.isEmpty() ? null : auds;
}
+ /**
+ * Parse the single logout URIs from the given role descriptor. Only the single logout service URLs whose binding
+ * matches to the one given in the parameters are taken into consideration.
+ *
+ * @param roleDescriptor The role descriptor to parse from.
+ * @param binding The binding to look after.
+ * @return The set of single logout URIs that were successfully parsed.
+ */
+ @Nonnull protected Set<URI> parseLogoutUris(@Nonnull final SPSSODescriptor roleDescriptor,
+ @Nonnull final String binding) {
+ final Set<URI> uris = new HashSet<>();
+ for (final SingleLogoutService slo : roleDescriptor.getSingleLogoutServices()) {
+ if (binding.equals(slo.getBinding())) {
+ final URI uri = getSingleURIValue(slo.getLocation());
+ if (uri != null) {
+ uris.add(uri);
+ }
+ }
+ }
+ return uris;
+ }
+
/**
* Parse an XML value list from a metadata value object into a collection of strings.
*
diff --git a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/ClientInformationNodeProcessorTest.java b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/ClientInformationNodeProcessorTest.java
index bdd0a51..a983f9d 100644
--- a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/ClientInformationNodeProcessorTest.java
+++ b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/impl/ClientInformationNodeProcessorTest.java
@@ -143,7 +143,19 @@ public class ClientInformationNodeProcessorTest extends XMLObjectBaseTestCase {
validate(role, true);
}
+ @Test
+ public void testParsedXMLMetadataWithLogoutURIs() throws Exception {
+ final RoleDescriptor role =
+ parseRoleDescriptor("/net/shibboleth/oidc/metadata/impl/EntitiesDescriptor-with-oidcmd-logout.xml");
+ validate(role, false, "https://example.org/slo-back", "https://example.org/slo-front");
+ }
+
private void validate(final RoleDescriptor role, final boolean jwkdata) throws Exception {
+ validate(role, jwkdata, null, null);
+ }
+
+ private void validate(final RoleDescriptor role, final boolean jwkdata, final String backChannelLogout,
+ final String frontChannelLogout) throws Exception {
Assert.assertNotNull(role);
Assert.assertTrue(role instanceof SPSSODescriptor);
final SPSSODescriptor sp = (SPSSODescriptor) role;
@@ -218,7 +230,23 @@ public class ClientInformationNodeProcessorTest extends XMLObjectBaseTestCase {
Assert.assertNull(metadata.getJWKSet());
Assert.assertEquals(metadata.getJWKSetURI(), new URI("https://example.org/jwks"));
}
-
+
+ if (backChannelLogout != null) {
+ Assert.assertEquals(metadata.getBackChannelLogoutURI(), new URI(backChannelLogout));
+ Assert.assertTrue(metadata.requiresBackChannelLogoutSession());
+ } else {
+ Assert.assertNull(metadata.getBackChannelLogoutURI());
+ Assert.assertFalse(metadata.requiresBackChannelLogoutSession());
+ }
+
+ if (frontChannelLogout != null) {
+ Assert.assertEquals(metadata.getFrontChannelLogoutURI(), new URI(frontChannelLogout));
+ Assert.assertTrue(metadata.requiresFrontChannelLogoutSession());
+ } else {
+ Assert.assertNull(metadata.getFrontChannelLogoutURI());
+ Assert.assertFalse(metadata.requiresFrontChannelLogoutSession());
+ }
+
final Set<URI> redirectUris = metadata.getRedirectionURIs();
Assert.assertEquals(redirectUris.size(), 2);
Assert.assertTrue(redirectUris.contains(new URI("https://example.org/cb")));
diff --git a/oidc-common-metadata-impl/src/test/resources/net/shibboleth/oidc/metadata/impl/EntitiesDescriptor-with-oidcmd-logout.xml b/oidc-common-metadata-impl/src/test/resources/net/shibboleth/oidc/metadata/impl/EntitiesDescriptor-with-oidcmd-logout.xml
new file mode 100644
index 0000000..f626fa4
--- /dev/null
+++ b/oidc-common-metadata-impl/src/test/resources/net/shibboleth/oidc/metadata/impl/EntitiesDescriptor-with-oidcmd-logout.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntitiesDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Name="RP test">
+
+ <md:EntityDescriptor entityID="mockSamlClientId">
+
+ <md:SPSSODescriptor xmlns:oidcmd="urn:mace:shibboleth:metadata:oidc:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" protocolSupportEnumeration="http://openid.net/specs/openid-connect-core-1_0.html">
+ <md:Extensions>
+ <oidcmd:OAuthRPExtensions
+ application_type="web"
+ client_uri="https://example.org/clientUri"
+ grant_types="authorization_code"
+ response_types="code code+id_token id_token+token id_token"
+ scopes="openid profile"
+ initiate_login_uri="https://example.org/initiateLogin"
+ software_id="mockSoftwareId"
+ software_version="mockSoftwareVersion"
+ token_endpoint_auth_method="client_secret_basic"
+ sector_identifier_uri="https://example.org/sectorIdentifier"
+ id_token_signed_response_alg="RS512"
+ id_token_encrypted_response_alg="A256KW"
+ id_token_encrypted_response_enc="A256GCM"
+ userinfo_signed_response_alg="RS384"
+ userinfo_encrypted_response_alg="A192KW"
+ userinfo_encrypted_response_enc="A192GCM"
+ request_object_signing_alg="RS256"
+ request_object_encryption_alg="A128KW"
+ request_object_encryption_enc="A128GCM"
+ token_endpoint_auth_signing_alg="RS512"
+ frontchannel_logout_session_required="true"
+ backchannel_logout_session_required="true" >
+ <oidcmd:default_acr_value>password</oidcmd:default_acr_value>
+ <oidcmd:default_acr_value>mfa</oidcmd:default_acr_value>
+ <oidcmd:request_uri>https://example.org/request</oidcmd:request_uri>
+ <oidcmd:post_logout_redirect_uri>https://example.org/postLogout</oidcmd:post_logout_redirect_uri>
+ </oidcmd:OAuthRPExtensions>
+ </md:Extensions>
+
+ <md:KeyDescriptor use="signing">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:KeyName>mockX509RSA</ds:KeyName>
+ <ds:X509Data>
+ <ds:X509Certificate>
+ MIIEQDCCAqigAwIBAgIVAIarXvdvyS47KJR7U40FlTufyD8vMA0GCSqGSIb3DQEB
+ CwUAMCAxHjAcBgNVBAMMFWxvY2FsaG9zdC5sb2NhbGRvbWFpbjAeFw0xOTA2MTcx
+ MTI5MTJaFw0zOTA2MTcxMTI5MTJaMCAxHjAcBgNVBAMMFWxvY2FsaG9zdC5sb2Nh
+ bGRvbWFpbjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALXysGFnoBFh
+ oasd5uMecp9OTBjvztntPUVmHfm4R3AcItEMEZEN/pETcX/wgKdo4qCBq4PrZITa
+ T8Salgl0XL6qF1Wia3JNA7Hh/OaoQEUsbsHgsjLMKt6MJh8vIaE1o8loL7Ay4WmZ
+ Cr3wc8ZS6CpMsv+qbxkyfl1h7MTydETnQhg/X83bj+BjJSh7QeFU0d0SWK1dN2/D
+ nFoGOfuTfVqeDRIwMxKlR5G//8N202sLaG28NljaHhLn3jHXeiGpCQ+Q2X90dkFb
+ EKb6sQ6SlDUAzm9MwLYjglDyOhXpUqOnvD67nggLb4Gn/4k+g5wtdfr7unOJYcHK
+ w7JGnI8Gd0lJMd6B3SpkhUOWgKv/D6HIBArhqSEmXuTyy8FewyYuo1XkIw/Lu3bB
+ 9qoBojM1tygoGlKi7R7e719J+DSkhyGbMyQ59leoN97iGGgqjUWS5mew8zSNviyz
+ 4uGqvxmLWU9UTH1YhlARsBF1bMiMnwLz7dF74AaAkC4pN3BYzDMyHQIDAQABo3Ew
+ bzAdBgNVHQ4EFgQUwKUd9D1Qymu2oBEVTscrAhP+sIUwTgYDVR0RBEcwRYIVbG9j
+ YWxob3N0LmxvY2FsZG9tYWluhixodHRwczovL2xvY2FsaG9zdC5sb2NhbGRvbWFp
+ bi9pZHAvc2hpYmJvbGV0aDANBgkqhkiG9w0BAQsFAAOCAYEAEYqh54a+j5OuR1UB
+ /AT9k2xXVwHiqQXAC/2un8O5BWAOeOq9+0gLJO5yaJp5c9GjPXRJmnDfGP9HFF6R
+ CjngtRCm1gV/fpj97IRQS5oroaeTWPQ9ZD5+ogs5DNt6UZeJ2GqpfA5mOytNg3cM
+ OP1B5QnA1apOaG4FHTegJR7WOIXkkAjEJUy6R+5Q6At7DdK/SRrP5onVPFv2HgGF
+ E9v9iX/uQepDizS5F2oi6LZCl1/b38gxA8BFL7VZu53JQguaA7SrnP+dBOErT/yh
+ Qcx3e9wE2ms8H1qISIdl3e7gvLi5jEyDWC9Agde6EjjvVVJAF7jR0puQ39mBfoxP
+ moVdHJQmCt3V7Ew9tYZUpG3rjp4YNXOiM+QhtwhHWT94q9uJKUQ6JvbxgLNDs5KM
+ 3PENx2C60TPFne9nRRIMVDavU4wwY7GdCgeo8PiZ5zxI0ZCkxh38ODePtKQrxJ7i
+ E0J1BE2LIxa1T7KY0XKpsH0iI2dNfZfNpNp4v/HiDb4svYgq</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor use="signing">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:KeyName>mockX509EC</ds:KeyName>
+ <ds:X509Data>
+ <ds:X509Certificate>
+ MIIBKDCBzgIJAOYlspXlaqguMAoGCCqGSM49BAMCMBwxCzAJBgNVBAYTAkZJMQ0w
+ CwYDVQQDDAR0ZXN0MB4XDTE5MTEwMTA4Mjg0OVoXDTIwMTAzMTA4Mjg0OVowHDEL
+ MAkGA1UEBhMCRkkxDTALBgNVBAMMBHRlc3QwWTATBgcqhkjOPQIBBggqhkjOPQMB
+ BwNCAARCUOlFMtRj3MIbdCzXmoGz4giDwjzPoX4AxMehhlXmPOodQhLDdvDqx3KE
+ hqadzIIsKHRQPDycscpHWpPbaQ2VMAoGCCqGSM49BAMCA0kAMEYCIQCVykSuUjlX
+ j4lxI6YqgYVuuhL2rG4hIrXw/pCey7eF2gIhAOSSaS025lQWy09W4NlnO28OkHoI
+ +Hbap7+DQlhbbr2d</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor use="signing">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:KeyName>mockRSA</ds:KeyName>
+ <ds:KeyValue>
+ <ds:RSAKeyValue>
+ <ds:Modulus>
+ AMP1p7GwPH64UPvBKD4DK0I6SDY7dtFPzL7L5qAIEJwIBBeDmLfVY/f9mLzDuDb19XzQxc6GEcjj
+ K8qRe7JAD3CE1IXXD0hKSOJ7H+chWS84iv7UNukbHHBO1oaRgfHh7vbX7HnpYMoqKK75rfiQqD9e
+ XOa2FLiH1QvnhLGKJcN+OKujetTgAhxE7ski9Gtfhhbt1qCEl7XtaUCLLexyrwWxx+NRxFgMU+nt
+ IZQ+T8ii+JQSWnRh14PGc+K9o1dp+vjse62hFprVQhhcbAKAkWpbup77NvvuTZ2+AtUhOuNHrH2I
+ X3jHeSWH7EzTGkPLGS6bFnYJQBqWv0POytfSyMM=</ds:Modulus>
+ <ds:Exponent>AQAB</ds:Exponent>
+ </ds:RSAKeyValue>
+ </ds:KeyValue>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor>
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:KeyName>mockJwksUri</ds:KeyName>
+ <oidcmd:JwksUri>https://example.org/jwks</oidcmd:JwksUri>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor>
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:KeyName>mockClientSecret</ds:KeyName>
+ <oidcmd:ClientSecret>mockClientSecretValue</oidcmd:ClientSecret>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:SingleLogoutService
+ Binding="https://openid.net/specs/openid-connect-frontchannel-1_0.html"
+ Location="https://example.org/slo-front"/>
+ <md:SingleLogoutService
+ Binding="https://openid.net/specs/openid-connect-backchannel-1_0.html"
+ Location="https://example.org/slo-back"/>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
+ <md:NameIDFormat>urn:mace:shibboleth:metadata:oidc:1.0:nameid-format:pairwise</md:NameIDFormat>
+ <md:AssertionConsumerService
+ Binding="https://tools.ietf.org/html/rfc6749#section-3.1.2"
+ Location="https://example.org/cb"
+ index="1"/>
+ <md:AssertionConsumerService
+ Binding="https://tools.ietf.org/html/rfc6749#section-3.1.2"
+ Location="https://example.org/cb2"
+ index="2"/>
+ <md:AssertionConsumerService
+ Binding="http://example.org/not/supported/profile/id"
+ Location="https://example.org/cb3"
+ index="3"/>
+ </md:SPSSODescriptor>
+
+ </md:EntityDescriptor>
+
+</md:EntitiesDescriptor>
\ No newline at end of file
diff --git a/oidc-common-saml-api/src/main/java/net/shibboleth/oidc/saml/xmlobject/OAuthRPExtensions.java b/oidc-common-saml-api/src/main/java/net/shibboleth/oidc/saml/xmlobject/OAuthRPExtensions.java
index eff9478..31bbb46 100644
--- a/oidc-common-saml-api/src/main/java/net/shibboleth/oidc/saml/xmlobject/OAuthRPExtensions.java
+++ b/oidc-common-saml-api/src/main/java/net/shibboleth/oidc/saml/xmlobject/OAuthRPExtensions.java
@@ -117,6 +117,14 @@ public interface OAuthRPExtensions extends SAMLObject, AttributeExtensibleXMLObj
/** Attribute local name. */
@Nonnull @NotEmpty public static final String REQUIRE_AUTH_TIME_ATTRIB_NAME = "require_auth_time";
+ /** Attribute local name. */
+ @Nonnull @NotEmpty public static final String BACK_CHANNEL_LOGOUT_SESSION_REQUIRED_ATTRIB_NAME =
+ "backchannel_logout_session_required";
+
+ /** Attribute local name. */
+ @Nonnull @NotEmpty public static final String FRONT_CHANNEL_LOGOUT_SESSION_REQUIRED_ATTRIB_NAME =
+ "frontchannel_logout_session_required";
+
/**
* Get the token endpoint authentication method.
*
@@ -417,7 +425,7 @@ public interface OAuthRPExtensions extends SAMLObject, AttributeExtensibleXMLObj
* @return The flag to require authentication time.
*/
public boolean isRequireAuthTime();
-
+
/**
* Set the flag to require authentication time.
*
@@ -425,6 +433,42 @@ public interface OAuthRPExtensions extends SAMLObject, AttributeExtensibleXMLObj
*/
public void setRequireAuthTime(final boolean flag);
+ /**
+ * Set the flag to require session id in back-channel logout request.
+ *
+ * @param flag The flag to require session id in back-channel logout request.
+ *
+ * @since 2.2.0
+ */
+ public void setBackChannelLogoutSessionRequired(final boolean flag);
+
+ /**
+ * Get the flag to require session id in back-channel logout request.
+ *
+ * @return The flag to require session id in back-channel logout request.
+ *
+ * @since 2.2.0
+ */
+ public boolean isBackChannelLogoutSessionRequired();
+
+ /**
+ * Set the flag to require session id in front-channel logout request.
+ *
+ * @param flag The flag to require session id in front-channel logout request.
+ *
+ * @since 2.2.0
+ */
+ public void setFrontChannelLogoutSessionRequired(final boolean flag);
+
+ /**
+ * Get the flag to require session id in front-channel logout request.
+ *
+ * @return The flag to require session id in front-channel logout request.
+ *
+ * @since 2.2.0
+ */
+ public boolean isFrontChannelLogoutSessionRequired();
+
/**
* Get the list of default ACR values.
*
diff --git a/oidc-common-saml-api/src/main/resources/schema/saml-metadata-ext-oidcmd.xsd b/oidc-common-saml-api/src/main/resources/schema/saml-metadata-ext-oidcmd.xsd
index ff61873..cee0093 100644
--- a/oidc-common-saml-api/src/main/resources/schema/saml-metadata-ext-oidcmd.xsd
+++ b/oidc-common-saml-api/src/main/resources/schema/saml-metadata-ext-oidcmd.xsd
@@ -57,6 +57,8 @@
<attribute name="initiate_login_uri" type="oidcmd:anyURI" />
<attribute name="default_max_age" type="int" />
<attribute name="require_auth_time" type="boolean" />
+ <attribute name="frontchannel_logout_session_required" type="boolean" />
+ <attribute name="backchannel_logout_session_required" type="boolean" />
<anyAttribute namespace="##other" processContents="lax" />
</complexType>
</element>
diff --git a/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsImpl.java b/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsImpl.java
index 4025de9..3c3f3f6 100644
--- a/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsImpl.java
+++ b/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsImpl.java
@@ -105,6 +105,12 @@ public class OAuthRPExtensionsImpl extends AbstractXMLObject implements OAuthRPE
/** Require auth time flag for this entity. */
private boolean requireAuthTime;
+ /** Require back-channel logout session id flag for this entity. */
+ private boolean backChannelLogoutSessionRequired;
+
+ /** Require front-channel logout session id flag for this entity. */
+ private boolean frontChannelLogoutSessionRequired;
+
/** Default ACR values for this entity. */
private final XMLObjectChildrenList<DefaultAcrValue> defaultAcrValues;
@@ -404,4 +410,23 @@ public class OAuthRPExtensionsImpl extends AbstractXMLObject implements OAuthRPE
return (List<XMLObject>) unknownChildren.subList(typeOrName);
}
+ /** {@inheritDoc} */
+ public void setBackChannelLogoutSessionRequired(boolean flag) {
+ backChannelLogoutSessionRequired = flag;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isBackChannelLogoutSessionRequired() {
+ return backChannelLogoutSessionRequired;
+ }
+
+ /** {@inheritDoc} */
+ public void setFrontChannelLogoutSessionRequired(boolean flag) {
+ frontChannelLogoutSessionRequired = flag;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isFrontChannelLogoutSessionRequired() {
+ return frontChannelLogoutSessionRequired;
+ }
}
diff --git a/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsMarshaller.java b/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsMarshaller.java
index 58c1a3c..b8aee15 100644
--- a/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsMarshaller.java
+++ b/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsMarshaller.java
@@ -146,6 +146,16 @@ public class OAuthRPExtensionsMarshaller extends AbstractSAMLObjectMarshaller {
Boolean.toString(rpExtensions.isRequireAuthTime()));
}
+ if (rpExtensions.isBackChannelLogoutSessionRequired()) {
+ domElement.setAttributeNS(null, OAuthRPExtensions.BACK_CHANNEL_LOGOUT_SESSION_REQUIRED_ATTRIB_NAME,
+ Boolean.toString(rpExtensions.isBackChannelLogoutSessionRequired()));
+ }
+
+ if (rpExtensions.isFrontChannelLogoutSessionRequired()) {
+ domElement.setAttributeNS(null, OAuthRPExtensions.FRONT_CHANNEL_LOGOUT_SESSION_REQUIRED_ATTRIB_NAME,
+ Boolean.toString(rpExtensions.isFrontChannelLogoutSessionRequired()));
+ }
+
marshallUnknownAttributes(rpExtensions, domElement);
}
diff --git a/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsUnmarshaller.java b/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsUnmarshaller.java
index e080bbf..86b1f35 100644
--- a/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsUnmarshaller.java
+++ b/oidc-common-saml-impl/src/main/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsUnmarshaller.java
@@ -102,6 +102,14 @@ public class OAuthRPExtensionsUnmarshaller extends AbstractSAMLObjectUnmarshalle
descriptor.setTokenEndpointAuthSigningAlg(attribute.getValue());
} else if (attribute.getLocalName().equals(OAuthRPExtensions.INITIATE_LOGIN_URI_ATTRIB_NAME)) {
descriptor.setInitiateLoginUri(attribute.getValue());
+ } else if (attribute.getLocalName().equals(
+ OAuthRPExtensions.BACK_CHANNEL_LOGOUT_SESSION_REQUIRED_ATTRIB_NAME)
+ && !Strings.isNullOrEmpty(attribute.getValue())) {
+ descriptor.setBackChannelLogoutSessionRequired(Boolean.parseBoolean(attribute.getValue()));
+ } else if (attribute.getLocalName().equals(
+ OAuthRPExtensions.FRONT_CHANNEL_LOGOUT_SESSION_REQUIRED_ATTRIB_NAME)
+ && !Strings.isNullOrEmpty(attribute.getValue())) {
+ descriptor.setFrontChannelLogoutSessionRequired(Boolean.parseBoolean(attribute.getValue()));
} else {
super.processAttribute(samlObject, attribute);
}
diff --git a/oidc-common-saml-impl/src/test/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsTest.java b/oidc-common-saml-impl/src/test/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsTest.java
index 32366fc..d553cd7 100644
--- a/oidc-common-saml-impl/src/test/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsTest.java
+++ b/oidc-common-saml-impl/src/test/java/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensionsTest.java
@@ -81,6 +81,8 @@ public class OAuthRPExtensionsTest extends XMLObjectProviderBaseTestCase {
rpExtensions.setUserInfoEncryptedResponseEnc("A192GCM");
rpExtensions.setUserInfoSignedResponseAlg("RS384");
rpExtensions.getUnknownAttributes().put(ATTRIBUTE_EXT_QNAME, ATTRIBUTE_EXT_VALUE);
+ rpExtensions.setBackChannelLogoutSessionRequired(true);
+ rpExtensions.setFrontChannelLogoutSessionRequired(true);
assertXMLEquals(expectedChildElementsDOM, rpExtensions);
}
@@ -142,6 +144,10 @@ public class OAuthRPExtensionsTest extends XMLObjectProviderBaseTestCase {
"The user info encrypted response enc did not have expected value");
Assert.assertEquals(rpExtensions.getUserInfoSignedResponseAlg(), "RS384",
"The user info signing response alg did not have expected value");
+ Assert.assertEquals(rpExtensions.isBackChannelLogoutSessionRequired(), true,
+ "The back-channel logout session id required did not have expected value");
+ Assert.assertEquals(rpExtensions.isFrontChannelLogoutSessionRequired(), true,
+ "The front-channel logout session id required did not have expected value");
}
protected <T extends MetadataValueSAMLObject> void assertMetadataValue(final T metadataValue,
diff --git a/oidc-common-saml-impl/src/test/resources/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensions.xml b/oidc-common-saml-impl/src/test/resources/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensions.xml
index 8d62d7c..a9059bf 100644
--- a/oidc-common-saml-impl/src/test/resources/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensions.xml
+++ b/oidc-common-saml-impl/src/test/resources/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensions.xml
@@ -21,7 +21,9 @@
request_object_signing_alg="RS256"
request_object_encryption_alg="A128KW"
request_object_encryption_enc="A128GCM"
- token_endpoint_auth_signing_alg="RS512">
+ token_endpoint_auth_signing_alg="RS512"
+ frontchannel_logout_session_required="true"
+ backchannel_logout_session_required="true" >
<oidcmd:default_acr_value>password</oidcmd:default_acr_value>
<oidcmd:default_acr_value>mfa</oidcmd:default_acr_value>
<oidcmd:request_uri>https://example.org/request</oidcmd:request_uri>
diff --git a/oidc-common-saml-impl/src/test/resources/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensions_ordered.xml b/oidc-common-saml-impl/src/test/resources/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensions_ordered.xml
index 8d62d7c..a9059bf 100644
--- a/oidc-common-saml-impl/src/test/resources/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensions_ordered.xml
+++ b/oidc-common-saml-impl/src/test/resources/net/shibboleth/oidc/saml/xmlobject/impl/OAuthRPExtensions_ordered.xml
@@ -21,7 +21,9 @@
request_object_signing_alg="RS256"
request_object_encryption_alg="A128KW"
request_object_encryption_enc="A128GCM"
- token_endpoint_auth_signing_alg="RS512">
+ token_endpoint_auth_signing_alg="RS512"
+ frontchannel_logout_session_required="true"
+ backchannel_logout_session_required="true" >
<oidcmd:default_acr_value>password</oidcmd:default_acr_value>
<oidcmd:default_acr_value>mfa</oidcmd:default_acr_value>
<oidcmd:request_uri>https://example.org/request</oidcmd:request_uri>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list