Search in sources :

Example 11 with AuthenticationContext

use of org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext in project identity-outbound-auth-sms-otp by wso2-extensions.

the class SMSOTPAuthenticator method getScreenValue.

/**
 * Get the screen value for configured screen attribute.
 *
 * @param context the AuthenticationContext
 * @return screenValue
 * @throws AuthenticationFailedException
 */
private String getScreenValue(AuthenticationContext context) throws AuthenticationFailedException {
    String screenValue;
    String username = String.valueOf(context.getProperty(SMSOTPConstants.USER_NAME));
    String tenantDomain = MultitenantUtils.getTenantDomain(username);
    String tenantAwareUsername = MultitenantUtils.getTenantAwareUsername(username);
    UserRealm userRealm = SMSOTPUtils.getUserRealm(tenantDomain);
    try {
        screenValue = getScreenAttribute(context, userRealm, tenantAwareUsername);
    } catch (UserStoreException e) {
        throw new AuthenticationFailedException("Failed to get the screen attribute for the user " + tenantAwareUsername + " from user store. ", e);
    }
    return screenValue;
}
Also used : UserRealm(org.wso2.carbon.user.api.UserRealm) AuthenticationFailedException(org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException) UserStoreException(org.wso2.carbon.user.api.UserStoreException)

Example 12 with AuthenticationContext

use of org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext in project identity-outbound-auth-sms-otp by wso2-extensions.

the class SMSOTPAuthenticator method getConnection.

/**
 * Get the connection and proceed with SMS API's rest call.
 *
 * @param httpConnection  the connection
 * @param context         the authenticationContext
 * @param headerString    the header string
 * @param payload         the payload
 * @param httpResponse    the http response
 * @param encodedMobileNo the encoded mobileNo
 * @param smsMessage      the sms message
 * @param otpToken        the token
 * @param httpMethod      the http method
 * @return true or false
 * @throws AuthenticationFailedException
 */
private boolean getConnection(HttpURLConnection httpConnection, AuthenticationContext context, String headerString, String payload, String httpResponse, String encodedMobileNo, String smsMessage, String otpToken, String httpMethod) throws AuthenticationFailedException {
    try {
        httpConnection.setDoInput(true);
        httpConnection.setDoOutput(true);
        String[] headerArray;
        if (StringUtils.isNotEmpty(headerString)) {
            if (log.isDebugEnabled()) {
                log.debug("Processing HTTP headers since header string is available");
            }
            headerString = headerString.trim().replaceAll("\\$ctx.num", encodedMobileNo).replaceAll("\\$ctx.msg", smsMessage + otpToken);
            headerArray = headerString.split(",");
            for (String header : headerArray) {
                String[] headerElements = header.split(":");
                if (headerElements.length > 1) {
                    httpConnection.setRequestProperty(headerElements[0], headerElements[1]);
                } else {
                    log.info("Either header name or value not found. Hence not adding header which contains " + headerElements[0]);
                }
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("No configured headers found. Header string is empty");
            }
        }
        // Processing HTTP Method
        if (log.isDebugEnabled()) {
            log.debug("Configured http method is " + httpMethod);
        }
        if (SMSOTPConstants.GET_METHOD.equalsIgnoreCase(httpMethod)) {
            httpConnection.setRequestMethod(SMSOTPConstants.GET_METHOD);
        } else if (SMSOTPConstants.POST_METHOD.equalsIgnoreCase(httpMethod)) {
            httpConnection.setRequestMethod(SMSOTPConstants.POST_METHOD);
            if (StringUtils.isNotEmpty(payload)) {
                payload = payload.replaceAll("\\$ctx.num", encodedMobileNo).replaceAll("\\$ctx.msg", smsMessage + otpToken);
            }
            OutputStreamWriter writer = null;
            try {
                writer = new OutputStreamWriter(httpConnection.getOutputStream(), SMSOTPConstants.CHAR_SET);
                writer.write(payload);
            } catch (IOException e) {
                throw new AuthenticationFailedException("Error while posting payload message ", e);
            } finally {
                if (writer != null) {
                    writer.close();
                }
            }
        }
        if (StringUtils.isNotEmpty(httpResponse)) {
            if (httpResponse.trim().equals(String.valueOf(httpConnection.getResponseCode()))) {
                if (log.isDebugEnabled()) {
                    log.debug("Code is successfully sent to the mobile and recieved expected response code : " + httpResponse);
                }
                return true;
            }
        } else {
            if (httpConnection.getResponseCode() == 200 || httpConnection.getResponseCode() == 201 || httpConnection.getResponseCode() == 202) {
                if (log.isDebugEnabled()) {
                    log.debug("Code is successfully sent to the mobile. Relieved HTTP response code is : " + httpConnection.getResponseCode());
                }
                return true;
            } else {
                context.setProperty(SMSOTPConstants.ERROR_CODE, httpConnection.getResponseCode() + " : " + httpConnection.getResponseMessage());
                log.error("Error while sending SMS: error code is " + httpConnection.getResponseCode() + " and error message is " + httpConnection.getResponseMessage());
                return false;
            }
        }
    } catch (MalformedURLException e) {
        throw new AuthenticationFailedException("Invalid URL ", e);
    } catch (ProtocolException e) {
        throw new AuthenticationFailedException("Error while setting the HTTP method ", e);
    } catch (IOException e) {
        throw new AuthenticationFailedException("Error while setting the HTTP response ", e);
    } finally {
        if (httpConnection != null) {
            httpConnection.disconnect();
        }
    }
    return false;
}
Also used : ProtocolException(java.net.ProtocolException) MalformedURLException(java.net.MalformedURLException) AuthenticationFailedException(org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException) OutputStreamWriter(java.io.OutputStreamWriter) IOException(java.io.IOException)

Example 13 with AuthenticationContext

use of org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext in project identity-outbound-auth-sms-otp by wso2-extensions.

the class SMSOTPAuthenticator method initiateAuthenticationRequest.

/**
 * Initiate the authentication request.
 */
@Override
protected void initiateAuthenticationRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws AuthenticationFailedException {
    try {
        String username;
        AuthenticatedUser authenticatedUser;
        String mobileNumber;
        String tenantDomain = context.getTenantDomain();
        context.setProperty(SMSOTPConstants.AUTHENTICATION, SMSOTPConstants.AUTHENTICATOR_NAME);
        if (!tenantDomain.equals(SMSOTPConstants.SUPER_TENANT)) {
            IdentityHelperUtil.loadApplicationAuthenticationXMLFromRegistry(context, getName(), tenantDomain);
        }
        FederatedAuthenticatorUtil.setUsernameFromFirstStep(context);
        username = String.valueOf(context.getProperty(SMSOTPConstants.USER_NAME));
        authenticatedUser = (AuthenticatedUser) context.getProperty(SMSOTPConstants.AUTHENTICATED_USER);
        // find the authenticated user.
        if (authenticatedUser == null) {
            if (log.isDebugEnabled()) {
                log.debug("Authentication failed: Could not find the authenticated user. ");
            }
            throw new AuthenticationFailedException("Authentication failed: Cannot proceed further without identifying the user. ");
        }
        boolean isSMSOTPMandatory = SMSOTPUtils.isSMSOTPMandatory(context, getName());
        boolean isUserExists = FederatedAuthenticatorUtil.isUserExistInUserStore(username);
        String queryParams = FrameworkUtils.getQueryStringWithFrameworkContextId(context.getQueryParams(), context.getCallerSessionKey(), context.getContextIdentifier());
        String errorPage = getErrorPage(context);
        // SMS OTP authentication is mandatory and user doesn't disable SMS OTP claim in user's profile.
        if (isSMSOTPMandatory) {
            if (log.isDebugEnabled()) {
                log.debug("SMS OTP is mandatory. Hence processing in mandatory path");
            }
            processSMSOTPMandatoryCase(context, request, response, queryParams, username, isUserExists);
        } else if (isUserExists && !SMSOTPUtils.isSMSOTPDisableForLocalUser(username, context, getName())) {
            if (context.isRetrying() && !Boolean.parseBoolean(request.getParameter(SMSOTPConstants.RESEND))) {
                checkStatusCode(response, context, queryParams, errorPage);
            } else {
                mobileNumber = getMobileNumber(request, response, context, username, tenantDomain, queryParams);
                if (StringUtils.isNotEmpty(mobileNumber)) {
                    proceedWithOTP(response, context, errorPage, mobileNumber, queryParams, username);
                }
            }
        } else {
            processFirstStepOnly(authenticatedUser, context);
        }
    } catch (SMSOTPException e) {
        throw new AuthenticationFailedException("Failed to get the parameters from authentication xml fie. ", e);
    } catch (UserStoreException e) {
        throw new AuthenticationFailedException("Failed to get the user from User Store. ", e);
    }
}
Also used : AuthenticationFailedException(org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException) UserStoreException(org.wso2.carbon.user.api.UserStoreException) SMSOTPException(org.wso2.carbon.identity.authenticator.smsotp.exception.SMSOTPException) AuthenticatedUser(org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser)

Example 14 with AuthenticationContext

use of org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext in project identity-outbound-auth-sms-otp by wso2-extensions.

the class SMSOTPAuthenticator method checkStatusCode.

/**
 * Check the status codes when resend and retry enabled.
 *
 * @param response    the HttpServletResponse
 * @param context     the AuthenticationContext
 * @param queryParams the queryParams
 * @param errorPage   the errorPage
 * @throws AuthenticationFailedException
 */
private void checkStatusCode(HttpServletResponse response, AuthenticationContext context, String queryParams, String errorPage) throws AuthenticationFailedException {
    boolean isRetryEnabled = SMSOTPUtils.isRetryEnabled(context, getName());
    String loginPage = getLoginPage(context);
    String url = getURL(loginPage, queryParams);
    if (StringUtils.isNotEmpty(getScreenValue(context))) {
        url = url + SMSOTPConstants.SCREEN_VALUE + getScreenValue(context);
    }
    try {
        String statusCode = (String) context.getProperty(SMSOTPConstants.STATUS_CODE);
        if (statusCode == null && isRetryEnabled) {
            response.sendRedirect(url + SMSOTPConstants.RESEND_CODE + SMSOTPUtils.isEnableResendCode(context, getName()) + SMSOTPConstants.RETRY_PARAMS);
        } else {
            if (Boolean.parseBoolean((String) context.getProperty(SMSOTPConstants.CODE_MISMATCH)) && !isRetryEnabled) {
                url = getURL(errorPage, queryParams);
                response.sendRedirect(url + SMSOTPConstants.RESEND_CODE + SMSOTPUtils.isEnableResendCode(context, getName()) + SMSOTPConstants.ERROR_CODE_MISMATCH);
            } else {
                response.sendRedirect(url + SMSOTPConstants.RESEND_CODE + SMSOTPUtils.isEnableResendCode(context, getName()) + SMSOTPConstants.RETRY_PARAMS);
            }
        }
    } catch (IOException e) {
        throw new AuthenticationFailedException("Authentication Failed: An IOException was caught. ", e);
    }
}
Also used : AuthenticationFailedException(org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException) IOException(java.io.IOException)

Example 15 with AuthenticationContext

use of org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext in project identity-outbound-auth-sms-otp by wso2-extensions.

the class SMSOTPAuthenticator method redirectToMobileNoReqPage.

/**
 * Redirect the user to mobile number request page.
 *
 * @param response    the HttpServletResponse
 * @param context     the AuthenticationContext
 * @param queryParams the queryParams
 * @throws AuthenticationFailedException
 */
private void redirectToMobileNoReqPage(HttpServletResponse response, AuthenticationContext context, String queryParams) throws AuthenticationFailedException {
    boolean isEnableMobileNoUpdate = SMSOTPUtils.isEnableMobileNoUpdate(context, getName());
    if (isEnableMobileNoUpdate) {
        String loginPage = SMSOTPUtils.getMobileNumberRequestPage(context, getName());
        try {
            String url = getURL(loginPage, queryParams);
            if (log.isDebugEnabled()) {
                log.debug("Redirecting to mobile number request page : " + url);
            }
            response.sendRedirect(url);
        } catch (IOException e) {
            throw new AuthenticationFailedException("Authentication failed!. An IOException was caught. ", e);
        }
    } else {
        throw new AuthenticationFailedException("Authentication failed!. Update mobile no in your profile.");
    }
}
Also used : AuthenticationFailedException(org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException) IOException(java.io.IOException)

Aggregations

PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)18 Test (org.testng.annotations.Test)18 AuthenticationContext (org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext)18 AuthenticationFailedException (org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException)9 IOException (java.io.IOException)5 UserStoreException (org.wso2.carbon.user.api.UserStoreException)5 Matchers.anyString (org.mockito.Matchers.anyString)4 UserRealm (org.wso2.carbon.user.api.UserRealm)4 HashMap (java.util.HashMap)2 AuthenticatorConfig (org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig)2 AuthenticatedUser (org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser)2 SMSOTPException (org.wso2.carbon.identity.authenticator.smsotp.exception.SMSOTPException)2 OutputStreamWriter (java.io.OutputStreamWriter)1 MalformedURLException (java.net.MalformedURLException)1 ProtocolException (java.net.ProtocolException)1 LocalApplicationAuthenticator (org.wso2.carbon.identity.application.authentication.framework.LocalApplicationAuthenticator)1 StepConfig (org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig)1 InvalidCredentialsException (org.wso2.carbon.identity.application.authentication.framework.exception.InvalidCredentialsException)1 RealmService (org.wso2.carbon.user.core.service.RealmService)1