SAML NameID Format not supported & Dynamic AttributeStatement

Dear community,

I have two questions releated to SAML 2.0

I’m trying to run a workflow in which I use Keycloak as an IDP provider.

Q1:
The client app which redirects user to keycloak wants that the NameId format policy is: <saml:NameID Format=“urn:oasis:names:tc:SAML:2.0:nameid-format:entity”>

However, as I can see in the admin console, only 4 following formats are supported:
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>

What could I do to force the server to use the nameid-format:entity format ?

Q2:
When the client apps wants a response with additional attributes in the AttributeStatement tag like this :

<saml:AttributeStatement>
<saml:Attribute Name=“signature_hash”>
<saml:AttributeValue>
1234567890ABCDEF1234567890ABCDEF12341234
</saml:AttributeValue>
<saml:AttributeValue>
9876543210ABCDEF1234567890ABCDEF12341234
<saml:AttributeValue>
</saml:Attribute>
<saml:AttributeStatement>

The attribute values are dynamic, meaning that they should be sent to Keycloak along with the SAML authentication request. It seems to me that I can inject these values into extensions fields of the request.
What could I do to inject these parameters in the tags in the SAML response ?

Thank you

Hello Hoan,

Q1:

I’m afraid, but Keycloak (<=18) currently does not support the name nameid-format:entity out of the box.

However, if you really need to support this you could do the following:

  1. Create a custom SamlProtocol provider (class CustomSamlProtocol extends SamlProtocol)
    See: keycloak-extension-playground/simple-custom-saml-protocol at master · thomasdarimont/keycloak-extension-playground · GitHub
  2. Override org.keycloak.protocol.saml.SamlProtocol#getNameIdFormat and return the desired nameid format (org.keycloak.saml.common.constants.JBossSAMLURIConstants#NAMEID_FORMAT_ENTITY) for the specific client
  3. Override org.keycloak.protocol.saml.SamlProtocol#getNameId and return the desired nameid for the specific client

With this you should be able to send the proper SAML messages.

If you really Keycloak should support nameid-format:entity just create a feature request here: Issues · keycloak/keycloak · GitHub

In order to implement support for nameid-format:entity you need to adjust the following places:

Q2:

If I understand correctly you want to reflect information that the client application sends with the saml AuthnRequest.

in the saml response generated by Keycloak and sent back to the client.

You could try to implement a org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor that extract the desired data from the AuthnRequestType request and stores it temporarily in the AuthenticationSessionModel.

The implement a custom SAML Protocol mapper by extending AbstractSAMLProtocolMapper and extract the previously stored information from the AuthenticationSessionModel via session.getContext().getAuthenticationSession().

Then you can use the data to render your custom attribute statements via org.keycloak.protocol.saml.mappers.UserPropertyAttributeStatementMapper#transformAttributeStatement

HTH

Cheers,
Thomas

Hi @thomasdarimont

Thank you so much for your suggestion. I tried it and it worked well.

However, the current SAML assertion generated has:

<saml:Issuer>http://localhost:8080/realms/crypto</saml:Issuer>

How can I do to add the format nameid-format:entity for the Issuer ? The third party application in our product needs something like this:

<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://localhost:8080/realms/crypto</saml:Issuer>

Thank you so much,
Hoan

Thank @thomasdarimont, I could solve the problem by overwritting the org.keycloak.protocol.saml.SamlProtocol#authenticated

Hoan