HUE 的 SAML 身份验证在首次登录后撤销管理员访问权限

SAML authentication for HUE revoking admin access AFTER first login

我正在尝试为使用 AWS EMR 部署的 HUE 设置 SAML 身份验证,使用 Azure SSO 作为 IdP。我实际上可以让握手工作,用户正在登录 HUE,将网络登录详细信息与预先填充在 HUE 后端数据库中的用户名相匹配。我们首先在 HUE 中创建用户,该设置的一部分包括将一些带有“is_superuser”的用户设置为 TRUE。我明确寻找从 IdP 到 HUE 的唯一属性是 username/network-credential

我试图了解的行为是,第一个登录 HUE UI 的人正在通过 SAML 进行身份验证并登录,admin/superuser 权限完好无损。但是之后登录的任何设置为管理员的人都会丢失指示管理员的标志,即以普通用户身份登录。如果我之后手动进入并设置用户在 HUE 数据库中具有管理员访问权限并让用户再次登录,访问权限将被授予管理员权限并且问题似乎消失了但我不明白为什么每次登录后首先是删除这些权限?

我尝试在调试模式下设置 Django 以查看是否可以获得任何见解,但我能找到的唯一可能解释这一点的是:

  1. 我在第一次登录后而不是在任何其他登录后在 runcpserver.log 的输出中发现了这一行,并且在深入研究 class 时肯定提到了“is_superuser" 在那里。

backend INFO Augmenting users with class: <class 'desktop.auth.backend.DefaultUserAugmentor'>

但是,我不知道这是否应该只调用一次。如果它应该每次都被调用,我不知道如何从我可用的配置中强制调用它。

  1. 我在日志中发现的另一件让我产生怀疑的事情是我在每个用户尝试登录后发现的以下两行,除了第一行:
mdstore      ERROR    Unsupported binding: urn:oasis:names:tc:SAML:2.0:bindings:SOAP (https://sts.windows.net/xxxxxxx-xxxx-xxxx-xxxxx-xxxxxxxxxxxx/)
mdstore      ERROR    Unsupported binding: urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST (https://sts.windows.net/xxxxxxx-xxxx-xxxx-xxxxx-xxxxxxxxxxxx/)

但我预计这会导致用户在绑定出现问题时根本无法访问,而不是允许用户登录但更改所述用户的属性。

希望对此有任何想法或见解,因为这不是我特别了解的领域

通过代码终于找到了问题,我遇到的问题在这里: https://github.com/cloudera/hue/blob/master/desktop/libs/libsaml/src/libsaml/backend.py#L91

        # If the user already exists, we shouldn't change its superuser
        # privileges. However, if there's a naming conflict with a non-external
        # user, we should do the safe thing and turn off superuser privs.
        existing_profile = get_profile(user)
        if existing_profile.creation_method == UserProfile.CreationMethod.EXTERNAL.name:
          is_super = user.is_superuser

if 语句检查用户的创建方式是否与外部源(即 LDAP)相匹配,以确保 Django 数据库中没有重复的条目。由于我的所有用户都已预先填充到数据库中,因此第一个变量始终设置为“HUE”,第二个变量始终设置为“EXTERNAL”,因此 if 语句始终为 false。

这意味着即使我将其设置为超级用户,用户在创建时也不会继承此属性,除非它是我看到的第一个用户,因为这行代码: https://github.com/cloudera/hue/blob/master/desktop/libs/libsaml/src/libsaml/backend.py#L80

    if not UserProfile.objects.filter(creation_method=UserProfile.CreationMethod.EXTERNAL.name).exists():
      # If there are no LDAP users already in the system, the first one will
      # become a superuser
      is_super = True

它一直在执行,因为我没有使用 LDAP 或任何东西,我直接在 Django 中预填充数据库。

所以我的解决方法是删除第一个代码块中的 if 语句。我希望这可以节省我花了两周时间才找到的人:)