1
votes

I am using WSO2is-5.3.0 for OIDC with custom authenticator and custom claim handler.

My custom authenticator use a third party web service to authenticate the user and gets some claims in the response. The custom claim handler add some more claims from database to the id_token. So the id_token received by SP has "claims from service" + "claims from databse".

Everything is fine when I have only one service provider(lets say SP1). My problem starts from here:

I have added one more SP (as OIDC) with same configuration (with same custom authenticator) called SP2. When user take login in SP1, WSO2IS return the id_token with all claims, now user open the SP2 in other tab and got login directly without being asked for authentication (thanks to SSO) but.... the SP2 gets only the claims from database( from custom claim handler) and do not get any claims which were returned from custom authenticator. There is no error in the logs of WSO2.

So basically my SSO is not working at all. If required I can share my code but I think the problem here is either a bug or some missing configuration. Any idea guys????

Update: After a little POC I found that the "custom claim handler" is being called again for SP2 and recalculating the claims. Since the autheticator is not being called the claims from third party service are null. Following is the code:

Custom Authenticator: method processAuthenticationResponse

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

Custom Claim Handler: method 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"));

For SP2, since the authenticator is not called, there is no property in context for "customclaim1", "customclaim2" and "customclaim3". Hence SP2 only receives "customclaim4" and "customclaim5"

Any idea how to handle this scenario???

Note: The rest service used in authenticator can not be changed, it will return the claims only if called with correct username and password.

Update: Based on above observation, I have some more questions:

  1. Why does claim handler is being called again if user has an active session in WSO2?

  2. Does WSO2 store these claims in database/cache ? Can we use the database to get the claims next time in custom claim handler??

Update

After trying the solution by Nilasini, I got this error:

enter image description here

The thing is, I am not using any userstore to authenticate the user. In my custom authenticator, I got username and password from login page and invoke a third party authentication service (with some addition details). How to handle this case ??

1

1 Answers

2
votes

Yes identity server is getting the claims from the database [1]. what you could do to solve the issue is, create a custom local claim and mapped to an attribute which is available in your user store.

Eg:-enter image description here

enter image description here

Then mapped these claims to an oidc claim. enter image description here

Don't forget to add the oidc claims to the registry. enter image description here

After followed the above steps, assign the value for the claim http://test.wso2.org/claims/customname through your custom authenticator like below.

Custom Authenticator: method processAuthenticationResponse

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

Then in your custom claim handler just add only the claims you wanted to add from database response.

Custom Claim Handler: method handleLocalClaims

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

Now if you do the sso with two service providers, both service provider's will receive the claims "keplerNumber", "customname".

You could refer [2] and [3] to test this scenario with two OIDC applications. Follow [4] to get two OIDC sample applications (playground2,playground3) and then do an SSO with two sample application, invoke the userinfo for both applications.

[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