ruby - 通过 Keycloak API 添加用户时忽略 "realmRoles"参数

标签 ruby keycloak

我正在尝试通过 Keycloak API 创建用户,并且我想在首次添加时为其分配领域级别的角色。但是,它似乎不像文档所说的那样工作。

我知道我可以在初始创建用户请求之后简单地发出第二个向用户添加角色的 API 请求,但是:

  • 文档表明我不需要这样做。
  • 第二个 API 请求可能失败,使用户处于“未完成”状态。
  • 这会使我编写的代码比它需要的更复杂。

  • 为了在 irb 中对此进行测试,使用 keycloak Ruby gem,我首先从 Keycloak 请求访问 token :
    require 'keycloak'
    json = Keycloak::Client.get_token_by_client_credentials
    access_token = JSON.parse(json)['access_token']
    

    以下所有内容在 Keycloak 中创建一个用户,但没有“所有者”角色:
    Keycloak::Admin.generic_post('users', nil, { username: 'someone', realmRoles: ['owner'] }, access_token)
    Keycloak::Admin.generic_post('users', nil, { username: 'someone', realmRoles: ['1fff5f5f-7357-4f73-b45d-65ccd01f3bc8'] }, access_token)
    Keycloak::Admin.generic_post('users', nil, { username: 'someone', realmRoles: ['{"id":"1fff5f5f-7357-4f73-b45d-65ccd01f3bc8","name":"owner","description":"Indicates that a user is the owner of an organisation.","composite":false,"clientRole":false,"containerId":"MyRealmName"}'] }, access_token)
    

    尝试使用角色哈希而不是字符串会导致错误:
    Keycloak::Admin.generic_post('users', nil, { username: 'someone', realmRoles: [{"id"=>"1fff5f5f-7357-4f73-b45d-65ccd01f3bc8", "name"=>"owner", "description"=>"Indicates that a user is the owner of an organisation.", "composite"=>false, "clientRole"=>false, "containerId"=>"MyRealmName"}] }, access_token)
    
    Traceback (most recent call last):
          16: from /home/thomas/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
          15: from (irb):8
          14: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/keycloak-3.0.0/lib/keycloak.rb:541:in `generic_post'
          13: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/keycloak-3.0.0/lib/keycloak.rb:943:in `generic_request'
          12: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/keycloak-3.0.0/lib/keycloak.rb:915:in `block in generic_request'
          11: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/rest-client-2.0.2/lib/restclient.rb:71:in `post'
          10: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/rest-client-2.0.2/lib/restclient/request.rb:52:in `execute'
            9: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/rest-client-2.0.2/lib/restclient/request.rb:145:in `execute'
            8: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/rest-client-2.0.2/lib/restclient/request.rb:715:in `transmit'
            7: from /home/thomas/.rvm/rubies/ruby-2.6.3/lib/ruby/2.6.0/net/http.rb:920:in `start'
            6: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/rest-client-2.0.2/lib/restclient/request.rb:725:in `block in transmit'
            5: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/rest-client-2.0.2/lib/restclient/request.rb:807:in `process_result'
            4: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/keycloak-3.0.0/lib/keycloak.rb:916:in `block (2 levels) in generic_request'
            3: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/keycloak-3.0.0/lib/keycloak.rb:958:in `rescue_response'
            2: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/rest-client-2.0.2/lib/restclient/abstract_response.rb:103:in `return!'
            1: from /home/thomas/.rvm/gems/ruby-2.6.3/gems/rest-client-2.0.2/lib/restclient/abstract_response.rb:223:in `exception_with_response'
    RestClient::InternalServerError (500 Internal Server Error)
    

    Keycloak 打印以下内容,表明 - 正如预期的那样 - 角色应该是一个字符串数组,而不是散列:
    08:53:27,889 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-22) Uncaught server error: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
    at [Source: (io.undertow.servlet.spec.ServletInputStreamImpl); line: 1, column: 37] (through reference chain: org.keycloak.representations.idm.UserRepresentation["realmRoles"]->java.util.ArrayList[0])
    

    如果我传递单个字符串而不是数组,则会发生同样的事情,例如:
    Keycloak::Admin.generic_post('users', nil, { username: 'someone', realmRoles: 'owner' }, access_token)
    

    我做错了什么,或者这只是 Keycloak API 中的一个错误?

    引用
  • https://www.keycloak.org/docs-api/6.0/rest-api/index.html#_createuser
  • https://www.keycloak.org/docs-api/6.0/rest-api/index.html#_userrepresentation

  • 类似问题
  • Keycloak : unable to map user roles when creating user for api
  • Keycloak: roles not assigned when user is created via CLI
  • 最佳答案

    你没有做错任何事。这是 Keycloak API 中的一个错误。

    此请求应该有效:

    Keycloak::Admin.generic_post('users', nil, { username: 'someone', realmRoles: ['owner'] }, access_token)
    

    不幸的是,API 文档是错误的,因为“realmRoles”属性在尝试创建/更新用户/组时不起作用。

    您可以在 Keycloak 的官方错误跟踪器上找到有关行为的更多信息:
  • https://issues.jboss.org/browse/KEYCLOAK-3410
  • https://issues.jboss.org/browse/KEYCLOAK-10876
  • https://issues.jboss.org/browse/KEYCLOAK-5038
  • ...

  • 目前唯一的解决方案是在 API 上发出多个请求,使用 RoleMappers 将角色映射到用户。

    有关这些操作的文档:https://www.keycloak.org/docs-api/6.0/rest-api/index.html#_role_mapper_resource

    关于ruby - 通过 Keycloak API 添加用户时忽略 "realmRoles"参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57390389/

    相关文章:

    ruby - 正则表达式提取两个字符串之间的字符串

    docker - 无法访问 Kubernetes 中的 Keycloak 帐户控制台 (403)

    angular - Keycloak - 页面刷新后注销时重定向到 "Confirm Logout"页面

    kubernetes - Kubernetes OpenID Connect身份验证失败时记录

    docker - 使用反向代理后面的 Keycloak 登录后无限循环

    ruby - 使用 ruby​​xl 创建使用相同模板的多个工作表

    ruby - 这个for循环是不愿意通过的,没有方法错误

    ruby - 在 ruby​​ 中从 iso-2022-jp 转换为 UTF

    saml - Keycloak 使用 SAML 注销

    Ruby:如何使用单个命令运行文件夹中的所有单元测试?