WSO2 IS 5.10自定义自适应函数无法设置Claim问题求助
问题:WSO2 IS 5.10自定义自适应函数添加Claim无效
使用WSO2 IS 5.10开发自定义自适应函数setForceAuth,意图添加自定义Claim,但在自适应认证脚本中调用该函数时无法生效,不过该函数在自定义认证器中可正常工作。
SetForceAuthFunctionImpl实现类代码
package org.wso2.custom.auth.functions; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import org.wso2.custom.auth.functions.internal.CustomAuthFuncComponent; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.*; public class SetForceAuthFunctionImpl implements SetForceAuthFunction { private static final Log LOGGER = LogFactory.getLog(SetForceAuthFunctionImpl.class); @Override public JsAuthenticatedUser setForceAuth(JsAuthenticationContext context, boolean forceAuth) { AuthenticatedUser lastAuthenticatedUser = context.getContext().getLastAuthenticatedUser(); LOGGER.info("lastAuthenticatedUser****:::::::::::"+lastAuthenticatedUser); String userName = lastAuthenticatedUser.getUserName(); LOGGER.info("userName2****:::::::::::"+userName); String tenantDomain = MultitenantUtils.getTenantDomain(userName); String fullyQualifiedUserName=("USERS"+"/"+userName+"@"+tenantDomain); Map<org.wso2.carbon.identity.application.common.model.ClaimMapping, String> claims = new HashMap<org.wso2.carbon.identity.application.common.model.ClaimMapping, String>(); claims.put(org.wso2.carbon.identity.application.common.model.ClaimMapping.build("test123", "test123", null, true), org.apache.commons.lang3.StringUtils.join("*******************",",,,")); AuthenticatedUser authenticatedUserObj = AuthenticatedUser.createLocalAuthenticatedUserFromSubjectIdentifier(MultitenantUtils.getTenantAwareUsername (fullyQualifiedUserName)); authenticatedUserObj.setAuthenticatedSubjectIdentifier(MultitenantUtils.getTenantAwareUsername (fullyQualifiedUserName)); authenticatedUserObj.setUserAttributes(claims); authenticatedUserObj.setUserName(MultitenantUtils.getTenantAwareUsername (fullyQualifiedUserName)); return new JsAuthenticatedUser(authenticatedUserObj); } }
CustomAuthFuncComponent组件代码
package org.wso2.custom.auth.functions.internal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicy; import org.wso2.carbon.identity.application.authentication.framework.JsFunctionRegistry; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.custom.auth.functions.GenerateHashFunction; import org.wso2.custom.auth.functions.GenerateHashFunctionImpl; import org.wso2.custom.auth.functions.GetClaimsForUsernameFunction; import org.wso2.custom.auth.functions.GetClaimsForUsernameFunctionImpl; import org.wso2.custom.auth.functions.GetUsernameFromContextFunction; import org.wso2.custom.auth.functions.GetUsernameFromContextFunctionImpl; import org.wso2.custom.auth.functions.SetForceAuthFunction; import org.wso2.custom.auth.functions.SetForceAuthFunctionImpl; @Component( name = "custom.auth.functions.component", immediate = true ) public class CustomAuthFuncComponent { private static final Log LOG = LogFactory.getLog(CustomAuthFuncComponent.class); private static JsFunctionRegistry jsFunctionRegistry; @Activate protected void activate(ComponentContext ctxt) { SetForceAuthFunction setForceAuthFunctionImpl = new SetForceAuthFunctionImpl(); jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "setForceAuth", setForceAuthFunctionImpl); GetUsernameFromContextFunction getUsernameFromContextFunctionImpl = new GetUsernameFromContextFunctionImpl(); jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getUsernameFromContext", getUsernameFromContextFunctionImpl); GetClaimsForUsernameFunction getClaimsForUsernameFunctionImpl = new GetClaimsForUsernameFunctionImpl(); jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getClaimsForUsername", getClaimsForUsernameFunctionImpl); GenerateHashFunction generateHashFunctionImpl = new GenerateHashFunctionImpl(); jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "generateHash", generateHashFunctionImpl); } @Deactivate protected void deactivate(ComponentContext ctxt) { if (jsFunctionRegistry != null) { jsFunctionRegistry.deRegister(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "setForceAuth"); jsFunctionRegistry.deRegister(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getUsernameFromContext"); jsFunctionRegistry.deRegister(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getClaimsForUsername"); jsFunctionRegistry.deRegister(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "generateHash"); } } @Reference( name = "user.realmservice.default", service = RealmService.class, cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC, unbind = "unsetRealmService" ) protected void setRealmService(RealmService realmService) { if (LOG.isDebugEnabled()) { LOG.debug("RealmService is set in the custom conditional authentication user functions bundle"); } CustomAuthFuncHolder.getInstance().setRealmService(realmService); } protected void unsetRealmService(RealmService realmService) { if (LOG.isDebugEnabled()) { LOG.debug("RealmService is unset in the custom conditional authentication user functions bundle"); } CustomAuthFuncHolder.getInstance().setRealmService(null); } @Reference( name = "registry.service", service = RegistryService.class, cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC, unbind = "unsetRegistryService" ) protected void setRegistryService(RegistryService registryService) { if (LOG.isDebugEnabled()) { LOG.debug("RegistryService is set in the custom conditional authentication user functions bundle"); } CustomAuthFuncHolder.getInstance().setRegistryService(registryService); } protected void unsetRegistryService(RegistryService registryService) { if (LOG.isDebugEnabled()) { LOG.debug("RegistryService is unset in the custom conditional authentication user functions bundle"); } CustomAuthFuncHolder.getInstance().setRegistryService(null); } @Reference( service = JsFunctionRegistry.class, cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC, unbind = "unsetJsFunctionRegistry" ) public void setJsFunctionRegistry(JsFunctionRegistry jsFunctionRegistry) { this.jsFunctionRegistry = jsFunctionRegistry; } public void unsetJsFunctionRegistry(JsFunctionRegistry jsFunctionRegistry) { this.jsFunctionRegistry = null; } }
自适应认证脚本代码
function onLoginRequest(context) { doLogin(context); } function doLogin(context) { executeStep(1,{ onSuccess: function (context) { }, onFail: function(context){ executeStep(4,{ onSuccess: function (context) { var subject = context.currentKnownSubject; setForceAuth(context, true); }, onFail: function(context){ } }); } }); }
排查要点及解决方案
上下文未更新
函数创建了新的AuthenticatedUser对象,但未将其设置回认证上下文。修改脚本调用逻辑:var updatedUser = setForceAuth(context, true); context.currentKnownSubject = updatedUser;Claim URI配置错误
代码中ClaimMapping.build的第一个参数应为合法的Claim URI(需提前在WSO2 IS控制台配置),而非自定义名称。修改示例:claims.put(ClaimMapping.build("http://wso2.org/claims/test123", "test123", null, true), "目标Claim值");用户标识符格式错误
fullyQualifiedUserName拼接格式不符合WSO2规范,本地用户标识符应为username@tenantdomain,无需前缀USERS/,修改代码:String fullyQualifiedUserName = userName + "@" + tenantDomain; AuthenticatedUser authenticatedUserObj = AuthenticatedUser.createLocalAuthenticatedUserFromSubjectIdentifier( MultitenantUtils.getTenantAwareUsername(userName) );函数注册子系统错误
自适应认证函数需注册到AUTHENTICATION子系统,而非SEQUENCE_HANDLER,修改组件激活方法中的注册代码:jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.AUTHENTICATION, "setForceAuth", setForceAuthFunctionImpl);
内容的提问来源于stack exchange,提问作者rahul
相关产品推荐
相关产品推荐

