wso2 / product-is

Welcome to the WSO2 Identity Server source code! For info on working with the WSO2 Identity Server repository and contributing code, click the link below.
http://wso2.github.io/
Apache License 2.0
734 stars 715 forks source link

WSO2 IS: Persistent Error Message in Threads After Password Grant Type with Blocked User #18669

Open leonardorobertolopez opened 7 months ago

leonardorobertolopez commented 7 months ago

Describe the issue: When attempting to use the password grant type, we have identified that the error message is not being cleared consistently when an error occurred during the flow. Here's a detailed explanation: We are using a OIDC Service Provider and executing the following curl command multiple times to test the password grant type: curl -u : -k -d "grant_type=password&username=&password=&scope=openid" -H "Content-Type:application/x-www-form-urlencoded" https://:/oauth2/token

In a log through a log patch, we first observe the clearing of the error message: [2023-12-18 21:04:49,037] INFO {org.wso2.carbon.identity.core.util.IdentityUtil} - Clearing error message java.lang.Throwable

Followed by setting a new error message: [2023-12-18 21:31:25,158] INFO {org.wso2.carbon.identity.core.util.IdentityUtil} - Setting error message with code 17003 to context java.lang.Throwable

However, the error message is not cleared subsequently.

How to reproduce:

  1. Use WSO2 IS 5.6.0. Tested for update level 52.
  2. Modify catalina-server.xml to reduce the maxThreads parameter to 2 or 3 in the configuration: port="9443" ... maxThreads="2"

2.b. Enable the account lock functionality at Resident idp level. For doing that please go to -Management Console > Identity Providers > Resident > Login Policies > Account Locking > and tick the flag:

"Account Lock Enabled"

  1. Configure a Service Provider with a multi-step authentication option (SAML or OIDC). In the first step, set up Basic Authenticator and an IdP Federated authenticator.
  2. Create another Service Provider for OIDC, Password Grant type.
  3. Create a user in the system and lock this user through the claim 'http://wso2.org/claims/identity/accountLocked', ensuring it is "Supported by Default". Lock the user via their user profile.
  4. Execute the following curl command 10 times for the SP created in step 4: curl -u : -k -d "grant_type=password&username=&password=&scope=openid" -H "Content-Type:application/x-www-form-urlencoded" https://:/oauth2/token

An example of this command is: curl --location 'https://localhost:9443/oauth2/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Authorization: Basic base64 cod:' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'username=' \ --data-urlencode 'password=' \ --data-urlencode 'scope=openid'

You can import it directly in Postman.

Note: Run this command 10 times to impact all threads in the system. When we say "impact," we refer to the scenario where if clearMessage() runs first followed by setMessage(), and clearMessage() is not executed again, the last error message set in setMessage() remains making that all the threads of the system don’t clear the error message properly. When we say "the last error message set in setMessage()" I refer to the below image that is obtained when login in again in another service provider. That is the evidence that in the thread the last error message hasn't been cleared properly .

Note: The above command should be executed with the credentials of the user created in step 5, generating the corresponding password lock error.

  1. After executing the password grant type command multiple times, access the SP created in step 3, you will observe the following error in the browser:

Error And in the wso2carbon.log: 2023-12-18 21:04:49,060] ERROR {org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator} - Exception in Authentication Framework java.lang.NullPointerException That is because, as we mentioned previously, the thread remains the error which hasn’t been cleared properly.

In summary, the purpose of this test is to demonstrate that the password grant type does not appropriately implement the clearMessage() function after the setMessage(). This could be reproduced for example when attempting to invoke the token endpoint using a blocked user. The absence of a subsequent clear after set means each thread does not clear the errors obtained from invoking the token endpoint. Consequently, when the same thread is reused in a different flow, such as a login flow with a multi-step option as explained in point nr 7 , an error is observed. This error does not pertain to the current flow but is instead a residual message stored in each thread from the previous operation. Thank you

Expected behavior: The error showed in the screen shouldnt take place because is not related with that flow.

Environment information

leonardorobertolopez commented 6 months ago

Hi Team: I added the step 2.b and improve the step nr 6 with an additional example and further explanation. Kindly let me know if additional details are needed. Thank you Best Regards