Skip to content

Keycloak: realm_access ignored if resource_access is present #83

@josefrcm

Description

@josefrcm

Hello, I am working on integrating a new Redmine installation with our existing Keycloak IdP, and I just finished fighting an annoying bug.

In my Keycloak server I had created a realm role called "admin" and assigned the proper users, and then in Redmine I had configured the "admin_group" setting as "admin", but still users login through OIDC connect were not assigned the administrator role inside Redmine. I verified that the "realm_access" claim was present in the generated JWT, but still Redmine seemed to ignore it. After some debugging, I think I found the cause.

In the file app/models/oic_session.rb, function check_keycloak_role:

def check_keycloak_role(role)
    # keycloak way...
    kc_is_in_role = false
    if user["realm_access"].present?
      kc_is_in_role = user["realm_access"]["roles"].include?(role)
    end
    if user["resource_access"].present? && user["resource_access"][client_config['client_id']].present?
      kc_is_in_role = user["resource_access"][client_config['client_id']]["roles"].include?(role)
    end
    return true if kc_is_in_role 
  end

So the function checks if the role is present in the "realm_access" claim, and then, whether it is present or not, checks if "resource_access" exists, and if so, overwrites the previously found value. My Keycloak server generates both, and thus the role present in "realm_access" was completely ignored.

I temporarily patched it on my server by the adding the following condition:

def check_keycloak_role(role)
    # keycloak way...
    kc_is_in_role = false
    if user["realm_access"].present?
      kc_is_in_role = user["realm_access"]["roles"].include?(role)
    end
    # skip the check if we already found the role
    if !kc_is_in_role and user["resource_access"].present? && user["resource_access"][client_config['client_id']].present?
      kc_is_in_role = user["resource_access"][client_config['client_id']]["roles"].include?(role)
    end
    return true if kc_is_in_role 
  end

Now my system works as intended, but I would like your opinion. In any case, thank you so much for your nice plugin!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions