我正在将WSO2is-5.3.0用于带有自定义身份验证器和自定义声明处理程序的OIDC。
我的自定义身份验证器使用第三方Web服务对用户进行身份验证,并在响应中获得一些声明。定制声明处理程序将更多声明从数据库添加到id_token。因此,SP收到的id_token具有“来自服务的声明” +“来自数据库的声明”。
当我只有一个服务提供商(让我说SP1)时,一切都很好。我的问题从这里开始:
我又添加了一个具有相同配置(具有相同的自定义身份验证器)的SP(作为OIDC),称为SP2。当用户在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”
任何想法如何处理这种情况?
注意:身份验证器中使用的其余服务无法更改,只有使用正确的用户名和密码调用时,它才会返回声明。
更新: 基于以上观察,我还有其他问题:
如果用户在WSO2中具有活动会话,为什么再次调用索赔处理程序?
WSO2是否将这些声明存储在数据库/缓存中?下次我们可以使用数据库在自定义索赔处理程序中获取索赔吗?
更新
尝试了Nilasini的解决方案后,出现了此错误:
问题是,我没有使用任何用户存储来认证用户。在我的自定义身份验证器中,我从登录页面获取了用户名和密码,并调用了第三方身份验证服务(以及一些其他详细信息)。如何处理这种情况?
答案 0 :(得分:2)
是的,身份服务器正在从数据库中获取声明[1]。解决该问题的方法是,创建一个自定义的本地声明,并将其映射到用户商店中可用的属性。
按照上述步骤操作后,通过您的自定义身份验证器为声明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");
现在,如果您对两个服务提供商进行sso,则两个服务提供商都将收到“ keplerNumber”,“ customname”的声明。
您可以参考[2]和[3]用两个OIDC应用程序来测试这种情况。按照[4]获得两个OIDC示例应用程序(playground2,playground3),然后对两个示例应用程序执行SSO,为这两个应用程序调用userinfo。
[2] https://github.com/nilasini/CustomBasicAuthenticator
[3] https://github.com/nilasini/CustomClaimHandler
[4] https://docs.wso2.com/display/IS530/Session+Management+with+Playground