使用 Ruby 2.7 读取 Keycloak OmniAuth::AuthHash 元素

Reading Keycloak OmniAuth::AuthHash elements with Ruby 2.7

从 Keycloak 身份验证令牌中,我读取了 OmniAuth::AuthHash 元素以提取用户名、电子邮件和角色。 根据通过 auth = request.env["omniauth.auth"] 语句检索到的令牌,读取姓名和电子邮件非常容易。 深入了解令牌的层次结构可提供请求的信息:

  user.name = auth.info.name
  user.uuid = auth.uid
  user.provider = auth.provider
  user.email = auth.info.email

我用同样的方法搜索用户的角色列表:

roles = auth.extra.raw_info.resource_access 提供以下 AuthHash:

#<OmniAuth::AuthHash 
    BFS.SIS=#<OmniAuth::AuthHash 
        roles=#<Hashie::Array 
            ["dataproducer", 
            "fsodataconsumer", 
            "sisdatasteward"]
            >
        > 
    BFS.SIS.DAL=#<OmniAuth::AuthHash 
        roles=#<Hashie::Array 
            ["kd_getLoadReports", 
            "kd_createTables", 
            "kd_readTables", 
            "kd_deleteTables"]
            >
        > 
    BFS.SIS.DPS.KEYSTORE=#<OmniAuth::AuthHash 
        roles=#<Hashie::Array 
            ["keymanagement_key_read", 
            "keymanagement_keystore_read"]
            >
        > 
    BFS.SIS.SMS=#<OmniAuth::AuthHash 
        roles=#<Hashie::Array 
            ["kdDatasetInformation_read", 
            "codeLists_update", 
            "definedVariables_set_status_validation_in_progress", 
            "hierarchicalCodeLists_update", 
            "hierarchicalCodeLists_create", 
            "kdDatasetInformation_delete", 
            "kdDatasetInformation_update", 
            "kdDataStructureDefinitions_create", 
            "kdDataStructureDefinitions_update", 
            "kdDataStructureDefinitions_delete", 
            "kdDataStructureDefinitions_read",
            "kdDatasetInformation_create", 
            "definedVariables_set_status_open_from_rejected"]
            >
        > 
    BFS.SIS.UI=#<OmniAuth::AuthHash 
        roles=#<Hashie::Array 
        ["bfs.sis.portal"]
        >
    >
>

存在问题: 由于键名包含“.”,我无法继续使用语法 key.subkey 访问子键来检索角色数组BFS.SIS 和 BFS.SIS.SMS 密钥。

如何从这些键中提取数组?

感谢您的帮助!

好吧,我无法深入研究散列 key.subkey 语法,但我可以枚举子键。然后我可以检查是否有一些匹配所需的条目,并提取子角色。

这是我实施的解决方案:

  auth = request.env["omniauth.auth"]
  roles = Array.new
  activities = auth.extra.raw_info.allowlists.statisticalActivities
  resources_accesses = auth.extra.raw_info.resource_access
  resources_accesses.each do |access|
    puts access # Provides the resources_access hash
    puts access[0] # Provides the resources_access label
    puts access[1] # Provides the resources_access roles array
    # Check if label matches needed entries
    if ["BFS.SIS.SMS", "BFS.SIS", "BFS.SIS.SCHEDULER"].include? access[0].to_s
      access[1].roles.each do |role|
        # Store each role in the roles array
        roles << role
      end
    end
  end

此用户角色列表将有助于构建 CanCanCan 的能力列表gem。