Skip to content

NullPointerException in SMSOTPAuthenticator when context.isRetrying() is true #21823

@vfraga

Description

@vfraga

Describe the issue:

image

The error displayed above is caused by an internal server error from an uncaught NullPointerException with the stack trace below:

ERROR {org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator} - Exception in Authentication Framework java.lang.NullPointerException
    at org.wso2.carbon.identity.authenticator.smsotp.SMSOTPAuthenticator.publishPostSMSOTPValidatedEvent(SMSOTPAuthenticator.java:1924)
    at org.wso2.carbon.identity.authenticator.smsotp.SMSOTPAuthenticator.process(SMSOTPAuthenticator.java:153)
    at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.doAuthentication(DefaultStepHandler.java:631)
    at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handle(DefaultStepHandler.java:363)
    . . .

Similar to [1], the reason seems to be that some properties aren't set when context.isRetrying() is true and, therefore, the retrieval fails.

Adding the EmailOTP's fix [2] to the SMSOTPAuthenticator addresses the error:

diff --git a/component/authenticator/src/main/java/org/wso2/carbon/identity/authenticator/smsotp/SMSOTPAuthenticator.java b/component/authenticator/src/main/java/org/wso2/carbon/identity/authenticator/smsotp/SMSOTPAuthenticator.java
index . . .
--- a/component/authenticator/src/main/java/org/wso2/carbon/identity/authenticator/smsotp/SMSOTPAuthenticator.java
+++ b/component/authenticator/src/main/java/org/wso2/carbon/identity/authenticator/smsotp/SMSOTPAuthenticator.java
@@ -125,6 +125,12 @@ public class SMSOTPAuthenticator extends AbstractApplicationAuthenticator implem
                                            HttpServletResponse response,
                                            AuthenticationContext context)
             throws AuthenticationFailedException, LogoutFailedException {
+
+        // If the current authenticator is not SMS OTP, then set the flow to not retrying which could have been
+        // set from other authenticators and not cleared.
+        if (!SMSOTPConstants.AUTHENTICATOR_NAME.equals(context.getCurrentAuthenticator())) {
+            context.setRetrying(false);
+        }
         // if the logout request comes, then no need to go through and complete the flow.
         if (context.isLogoutRequest()) {
             return AuthenticatorFlowStatus.SUCCESS_COMPLETED;
@@ -132,7 +138,8 @@ public class SMSOTPAuthenticator extends AbstractApplicationAuthenticator implem
             // if the request comes with MOBILE_NUMBER, it will go through this flow.
             initiateAuthenticationRequest(request, response, context);
             return AuthenticatorFlowStatus.INCOMPLETE;
-        } else if (StringUtils.isEmpty(request.getParameter(SMSOTPConstants.CODE))) {
+        } else if (StringUtils.isEmpty(request.getParameter(SMSOTPConstants.CODE)) &&
+                !Boolean.parseBoolean(request.getParameter(SMSOTPConstants.RESEND))) {
             // if the request comes with code, it will go through this flow.
             initiateAuthenticationRequest(request, response, context);
             publishPostSMSOTPGeneratedEvent(request, context);
(END)

How to reproduce:

  1. Set up an Identity Server instance with mail sending capabilities.
  2. Create one Identity Provider for Email OTP and another for SMS OTP.
  3. Create a Service Provider with adaptive authentication as below:
    • Step 1: Basic
    • Step 2: EmailOTP
    • Step 3: SMSOTP
    • Script:
 var onLoginRequest = function(context) {
     executeStep(1, {
         onSuccess: function (context) {
             executeStep(2, {
                 onFail: function (context) {
                     executeStep(3);
                 }
             });
         }        
     });
 };
  1. Log in with the correct credentials and provide invalid Email and SMS OTPs.

Expected behaviour:
The end user shouldn't be redirected to a generic error page from providing an invalid OTP, but rather kept in the page to allow them to provide a new code.

Environment information:

  • Product Version: IS 6.1.0

[1] #20282
[2] https://github.com/wso2-extensions/identity-outbound-auth-email-otp/pull/182/files

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions