【问题标题】:Claims are missing in OIDC SSO from WSO2IS-5.3.0WSO2IS-5.3.0 的 OIDC SSO 中缺少声明
【发布时间】:2018-08-07 20:52:45
【问题描述】:

我将 WSO2is-5.3.0 用于具有自定义身份验证器和自定义声明处理程序的 OIDC。

我的自定义身份验证器使用第三方网络服务对用户进行身份验证,并在响应中获得一些声明。自定义声明处理程序将更多声明从数据库添加到 id_token。所以 SP 收到的 id_token 有“来自服务的声明”+“来自数据库的声明”。

当我只有一个服务提供商(比如说 SP1)时,一切都很好。我的问题从这里开始:

我又添加了一个名为 SP2 的具有相同配置(具有相同自定义身份验证器)的 SP(作为 OIDC)。当用户在 SP1 中登录时,WSO2IS 返回带有所有声明的 id_token,现在用户在其他选项卡中打开 SP2 并直接登录而不被要求进行身份验证(感谢 SSO)但是.... SP2 只获得来自数据库的声明(来自自定义声明处理程序) 并且 不会 获得从自定义身份验证器返回的任何声明。 WSO2 的日志中没有错误。

所以基本上我的 SSO 根本不起作用。如果需要,我可以分享我的代码,但我认为这里的问题要么是错误,要么是缺少一些配置。有什么想法吗????

更新: 经过一点 POC,我发现再次为 SP2 调用“自定义索赔处理程序”并重新计算索赔。由于未调用身份验证器,因此来自第三方服务的声明为空。以下是代码:

自定义身份验证器: 方法processAuthenticationResponse

context.setProperty("customclaim1", restResponse.customclaim1);
context.setProperty("customclaim2", restResponse.customclaim2);
context.setProperty("customclaim3", restResponse.customclaim3);

自定义声明处理程序: 方法 handleLocalClaims

claims.put("customclaim4", "databaseResponse.customclaim4");
claims.put("customclaim5", "databaseResponse.customclaim5");            
claims.put("customclaim1", (String) context.getProperty("customclaim1"));
claims.put("customclaim2", (String) context.getProperty("customclaim2"));
claims.put("customclaim3", (String) context.getProperty("customclaim3"));

对于 SP2,由于不调用身份验证器,因此“customclaim1”、“customclaim2”和“customclaim3”的上下文中没有属性。因此 SP2 只接收“customclaim4”和“customclaim5”

知道如何处理这种情况吗???

注意: authenticator 中使用的 rest 服务不能更改,只有使用正确的用户名和密码调用才会返回声明。

更新: 基于以上观察,我还有一些问题:

  1. 如果用户在 WSO2 中有活动会话,为什么会再次调用声明处理程序?

  2. WSO2 是否将这些声明存储在数据库/缓存中?我们可以在自定义索赔处理程序中使用数据库下次获取索赔吗?

更新

在尝试了 Nilasini 的解决方案后,我得到了这个错误:

问题是,我没有使用任何用户存储来验证用户。在我的自定义身份验证器中,我从登录页面获取用户名和密码并调用第三方身份验证服务(带有一些附加细节)。这种情况怎么处理??

【问题讨论】:

    标签: wso2 wso2is openid-connect


    【解决方案1】:

    是的,身份服务器正在从数据库 [1] 中获取声明。你可以做些什么来解决这个问题,创建一个自定义的本地声明并映射到你的用户存储中可用的属性。

    例如:-

    然后将这些声明映射到 oidc 声明。

    不要忘记将 oidc 声明添加到注册表中。

    完成上述步骤后,通过您的自定义身份验证器为声明http://test.wso2.org/claims/customname分配值,如下所示。

    自定义身份验证器:方法 processAuthenticationResponse

    userStoreManager.setUserClaimValue(username, "http://test.wso2.org/claims/customname",
                    restResponse.customclaim1, "default");
    

    然后在您的自定义声明处理程序中只添加您想从数据库响应中添加的声明。

    自定义声明处理程序:方法 handleLocalClaims

    claims.put("keplerNumber", "databaseResponse.customclaim4");
    

    现在,如果您对两个服务提供商进行单点登录,那么这两个服务提供商都会收到声明“keplerNumber”、“customname”。

    您可以参考 [2] 和 [3] 以使用两个 OIDC 应用程序测试此场景。按照[4]获取两个OIDC示例应用程序(playground2,playground3),然后对两个示例应用程序进行SSO,调用两个应用程序的用户信息。

    [1]https://github.com/wso2/carbon-identity-framework/blob/master/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/claims/impl/DefaultClaimHandler.java#L595

    [2]https://github.com/nilasini/CustomBasicAuthenticator

    [3]https://github.com/nilasini/CustomClaimHandler

    [4]https://docs.wso2.com/display/IS530/Session+Management+with+Playground

    【讨论】:

    • 超级!!看起来它会解决我的问题。将在星期一试一试,让您知道结果并接受它作为答案。现在点赞?再次感谢?
    • 嗨 Nilasini,我遇到了另一个问题并更新了问题。你能看看吗??
    • 嘿@Nilasini,知道我该如何处理吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-30
    • 1970-01-01
    • 2012-10-04
    相关资源
    最近更新 更多