mrparkers / terraform-provider-keycloak

Terraform provider for Keycloak
https://registry.terraform.io/providers/mrparkers/keycloak/latest/docs
MIT License
607 stars 295 forks source link

How to add SAML X500 Predefined mapper? #844

Closed rgl closed 1 year ago

rgl commented 1 year ago

How do we add SAML X500 Predefined mapper?

For example, at the SAML Client UI page, Clients scopes tab:

image

Click the example-go-saml-dedicated (Dedicated scope and mappers for this client), and go to the page:

image

Click the Add predefined mapper, and choose, for example, X500 email:

image

Then its added as:

image

The following does not work due to invalid saml_attribute_name_format:

# see https://registry.terraform.io/providers/mrparkers/keycloak/latest/docs/resources/saml_user_attribute_protocol_mapper
resource "keycloak_saml_user_attribute_protocol_mapper" "example_go_saml_email" {
  realm_id                   = keycloak_saml_client.example_go_saml.realm_id
  client_id                  = keycloak_saml_client.example_go_saml.id
  name                       = "X500 email"
  user_attribute             = "email"
  saml_attribute_name        = "urn:oid:1.2.840.113549.1.9.1"
  saml_attribute_name_format = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
}

The following does not work either, because the SAML Assertion does not end up with the expected SAML attribute:

# see https://registry.terraform.io/providers/mrparkers/keycloak/latest/docs/resources/saml_user_attribute_protocol_mapper
resource "keycloak_saml_user_attribute_protocol_mapper" "example_go_saml_email" {
  realm_id                   = keycloak_saml_client.example_go_saml.realm_id
  client_id                  = keycloak_saml_client.example_go_saml.id
  name                       = "email"
  user_attribute             = "email"
  saml_attribute_name        = "email"
  saml_attribute_name_format = "Basic"
}

How to we replicate the UI actions?

raffraffraff commented 1 year ago

When I manually added the 'builtin' mappers for "X500 email" etc, the SAML attribute name format is blank. This goes against the Terraform Provider documentation which states that this attribute is required. I'm using keycloak v18, so they're not called "predefined" mappers, and the UI looks different. In fact, I don't see the 'long' form fo the format, I just see the options that the resource supports:

If the new Keycloak shows the long name format in the dropdown, perhaps that's the source of the confusion. In all of my cases, the realm export JSON shows that X500 protocol mappers use urn:oasis:names:tc:SAML:2.0:attrname-format:uri but the UI field is blank. I presume that if I change mine to "URI Reference" they will still work.

Have you tried using "URI Reference" instead of "Basic"?

You could also try adding the mapper manually in the UI that works, and then importing it into Terraform as per the example:

terraform import keycloak_saml_user_property_protocol_mapper.saml_user_property_mapper my-realm/client/a7202154-8793-4656-b655-1dd18c181e14/71602afa-f7d1-4788-8c49-ef8fd00af0f4

If that works, then a terraform plan might show you something useful.

rgl commented 1 year ago

That was it! I've somehow missed that we could use the URI Reference value.

With:

# see https://registry.terraform.io/providers/mrparkers/keycloak/latest/docs/resources/saml_user_attribute_protocol_mapper
# see https://www.keycloak.org/docs-api/21.1.1/javadocs/org/keycloak/models/UserModel.html
resource "keycloak_saml_user_attribute_protocol_mapper" "example_go_saml_email" {
  realm_id                   = keycloak_saml_client.example_go_saml.realm_id
  client_id                  = keycloak_saml_client.example_go_saml.id
  name                       = "email"
  user_attribute             = "email"
  saml_attribute_name        = "urn:oid:1.2.840.113549.1.9.1"
  saml_attribute_name_format = "URI Reference"
}

It now returns the expected SAML attribute:

      <Attribute
        Name="urn:oid:1.2.840.113549.1.9.1"
        NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
        <AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:type="xs:string">alice@example.com</AttributeValue>
      </Attribute>

Thank You!

BTW, I'm playing with this at https://github.com/rgl/terraform-keycloak

raffraffraff commented 1 year ago

Nice! I'll definitely be following your project because I have a ton of stuff to automate in Keycloak via Terraform.