Details

    • Steps to Reproduce:
      Hide
      1. Configure a client for AWS following this guide
      2. Try to login to AWS using Keycloak
      Show
      Configure a client for AWS following this guide Try to login to AWS using Keycloak
    • Docs QE Status:
      NEW
    • QE Status:
      NEW

      Description

      TL;DR

      There is a bug in Keycloak that when building a SAML response, a user defined attribute using the Role List Mapper is ignored. A role mapper with the default values is used instead.

      Story Time

      I have configure a SAML client in Keycloak to authenticate to AWS. When making use of it, AWS responded with:

      Error: Your Request Included an Invalid SAML Response. To Logout, Click Here.
      

      AWS documentation points to a missing attribute that specifies the roles of the user that needs to have the name "https://aws.amazon.com/SAML/Attributes/Role". This is weird as I have configured the attribute mappers, one of which is the roles one with the right name.

      By inspecting the SAML response send to AWS I was able to confirm that indeed the roles were being sent, but with the wrong attribute name as well as missing "Friendly Name":

      <saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
          <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">arn:aws:iam::XXXXXX:role/READ_ONLY,arn:aws:iam::XXXXXX:saml-provider/keycloak-sso</saml:AttributeValue>
      </saml:Attribute>
      

      After diving in Keycloak source code and remotely (painfully slow ) debugging the Keycloak test instance I was able to pinpoint where a fix could be applied to correct this behaviour. After that, the proper SAML response is sent:

      <saml:Attribute FriendlyName="Session Role" Name="https://aws.amazon.com/SAML/Attributes/Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
          <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">arn:aws:iam::XXXXXX:role/READ_ONLY,arn:aws:iam::XXXXXX:saml-provider/keycloak-sso</saml:AttributeValue>
      </saml:Attribute>
      

      The Fix
      Apparently the function call to "ProtocolMapperUtils.getSortedProtocolMappers" in "SamlProtocol.java:425" always returns a extra role list mapper with default values. This means that even though the user configured role list mapper is in the list of mappers, it gets overwritten by the one with default values in "SamlProtocol.java:436".

      The fix I implemented is to ensure that if the "roleListMapper" variable had already been set, not to overwrite it. I don't know enough of Keycloak's source code (first time playing with it ) to understand why the extra role mapper was being added even though one is already configured. Maybe a better fix is to allow multiple role list mappers (same as for attribute mappers).

      I have created a GitHub PR with the purported fix.

        Gliffy Diagrams

          Attachments

          1. aws-session-role.png
            aws-session-role.png
            40 kB
          2. debug-session.png
            debug-session.png
            171 kB
          3. image-2020-06-18-12-47-20-921.png
            image-2020-06-18-12-47-20-921.png
            34 kB
          4. image-2020-06-18-12-53-06-484.png
            image-2020-06-18-12-53-06-484.png
            38 kB
          5. image-2020-06-18-13-36-43-007.png
            image-2020-06-18-13-36-43-007.png
            48 kB
          6. query-results.png
            query-results.png
            43 kB

            Activity

              People

              • Assignee:
                hmlnarik Hynek Mlnařík
                Reporter:
                serializingme Duarte Silva
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: