Flask-OIDC |用户登录后如何调用特定函数

问题描述

我使用 Flask OIDC 和 Keycloak 构建了一个登录系统。在我的系统中,有一些端点用 oidc.require_login() 修饰,调用 Keycloak 登录页面

我的目标是,在用户成功登录后,我的系统会检查用户名是否存在于特定数据库中。

如何设置每次有人使用 Keycloak 成功登录并在数据库中进行此验证时调用函数

解决方法

根据您的需要,有多种方法可以在后台创建用户。

  • 最简单的方法是检查每个请求的 JWT 令牌。 OIDC 基于 JWT,该令牌可用于任何请求(应该已经完成​​以查找用户角色等)。因此,您的应用程序可以检查该 JWT 并从中提取用户名(有关 JWT 格式的详细信息,请参阅 here)。使用用户名,您可以检查您的内部数据库并创建用户(如果它不存在)。但届时您将无法再访问任何用户凭据。这只是 SSO,您需要信任 Keycloak 和 JWT...此外 - 如果用户将在 Keycloak 中被删除,您将永远不会收到通知,这可能是一个问题。

  • Keycloak 中有一个回调 API,以每个客户端的管理 URL 的形式出现。但是文档不清楚。它说: Keycloak 服务器使用它向应用程序发送后端请求以执行各种任务,例如注销用户或推送撤销策略。但我找不到完整的“任务”列表。我只看到注销事件。 see Keycloak documentation 和文档只讨论了这一点。如果我向测试客户端添加管理 url,我在登录时没有收到任何请求。

  • 另一种不同但更复杂的方法是在 Keycloak 中创建您自己的 UserStorage SPI。当然是Java,但只有一些类。有一个 HTTP example 或者看看 LDAP user storage SPI,它也支持注册。如果您为您的领域选择了它,并且用户尝试登录 Keycloak(登录表单),则 SPI 可以调用您的后端来检查用户。它还可以通过检查 Keycloak 本地存储“用于”在后端创建用户,并且仅当存在本地 Keycloak 用户时,才调用后端。这不是您应该实现 UserStorage SPI 的原因,但这是可能的。如果您认为这是一个好主意,我更愿意将您的后端存储用作唯一的存储或构建一个不同的存储,然后可以在新用户的情况下调用您的真实后端。我不会使用 Keycloak 本地存储用户,而是使用您自己的数据库来使用这个。

  • 下一个(可能是最后一个)。您可以编写一个 EventListener SPI 来读取所有事件并仅过滤登录事件,请参阅 herehere。我想,那将是最简单的一种。但要注意。在这种情况下,来自事件本身的对后端的 HTTP 调用基于正常的 HTTP 请求(当时没有 OIDC)。

最后两个示例创建了一个 JAR(在链接中进行了解释)。带有 SPI 的 JAR 必须部署在 keycloaks standalone/deployments 文件夹中。默认情况下,EventListener 应处于活动状态,必须为每个领域激活 UserStorage SPI。

但是 - 请注意 - Keycloak/SSO/JWT - 不应通过在多个后端创建用户来使用。在 SSO 环境中的所有后端之间同步用户可能是错误的方式。大多数信息位于 JWT 中,或者可以由一个中央用户身份管理的后端调用。不要多次存储用户。如果您在后端需要用户引用 - 仅链接到用户名或用户 ID(字符串)而不是完整的实体。

,

没有直接的方法可以做到这一点,Openam、Okta 等其他软件允许您在登录后配置中触发特定流程。

在 keycloak 中,您可以尝试创建自定义身份验证流程(使用默认身份提供程序,这是允许重定向的唯一选项),然后在登录后流程中在您的身份提供程序中选择此流程。

这里的想法是,登录后,用户将被重定向到一个链接(一个 api 调用,将验证他在外部数据库中的存在,并在验证完成后将他发送回 keycloak。

More info here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...