org.wso2.carbon.identity.authenticator.tiqr.TiqrAuthenticator.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.identity.authenticator.tiqr.TiqrAuthenticator.java

Source

/*
 *  Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

package org.wso2.carbon.identity.authenticator.tiqr;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.String;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.HttpURLConnection;
import java.lang.Integer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.identity.application.authentication.framework.AbstractApplicationAuthenticator;
import org.wso2.carbon.identity.application.authentication.framework.FederatedApplicationAuthenticator;
import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade;
import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig;
import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext;
import org.wso2.carbon.identity.application.authentication.framework.exception.*;
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants;
import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils;
import org.wso2.carbon.identity.application.common.model.Property;
import org.wso2.carbon.identity.application.authentication.framework.AuthenticatorFlowStatus;
import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig;
import org.wso2.carbon.identity.authenticator.tiqr.internal.TiqrAuthenticatorServiceComponent;
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.user.profile.mgt.UserProfileAdmin;
import org.wso2.carbon.identity.user.profile.mgt.UserProfileException;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.UserStoreManager;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;

/**
 * Authenticator of Tiqr
 */
public class TiqrAuthenticator extends AbstractApplicationAuthenticator
        implements FederatedApplicationAuthenticator {

    private static final long serialVersionUID = 1179165995021182755L;
    private static Log log = LogFactory.getLog(TiqrAuthenticator.class);

    @Override
    public AuthenticatorFlowStatus process(HttpServletRequest request, HttpServletResponse response,
            AuthenticationContext context) throws AuthenticationFailedException, LogoutFailedException {
        if (context.isLogoutRequest()) {
            return AuthenticatorFlowStatus.SUCCESS_COMPLETED;
        }
        return super.process(request, response, context);
    }

    /**
     * Check whether the authentication or logout request can be handled by the authenticator
     */
    @Override
    public boolean canHandle(HttpServletRequest request) {
        if (log.isDebugEnabled()) {
            log.debug("Inside TiqrAuthenticator.canHandle()");
        }
        return ((StringUtils.isNotEmpty(request.getParameter(TiqrConstants.TIQR_ACTION))
                && request.getParameter(TiqrConstants.TIQR_ACTION).equals(TiqrConstants.TIQR_ACTION_AUTHENTICATION))
                || (request.getParameter(TiqrConstants.ENROLL_USERID) != null
                        && request.getParameter(TiqrConstants.ENROLL_DISPLAYNAME) != null
                        && request.getParameter(TiqrConstants.AUTH_USERNAME) != null
                        && request.getParameter(TiqrConstants.AUTH_PASSWORD) != null));
    }

    /**
     * initiate the authentication request
     */
    @Override
    protected void initiateAuthenticationRequest(HttpServletRequest request, HttpServletResponse response,
            AuthenticationContext context) throws AuthenticationFailedException {
        try {
            Map<String, String> authenticatorProperties = context.getAuthenticatorProperties();
            if (authenticatorProperties != null) {
                String retryParam = "";
                if (context.isRetrying()) {
                    retryParam = "&authFailure=true";
                    if (request.getParameter(TiqrConstants.TIQR_ACTION)
                            .equals(TiqrConstants.TIQR_ACTION_ENROLLMENT)) {
                        retryParam = retryParam + "&authFailureMsg=enrollment.fail.message";
                    } else {
                        retryParam = retryParam + "&authFailureMsg=authentication.fail.message";
                    }
                }
                String enrollmentPage = ConfigurationFacade.getInstance().getAuthenticationEndpointURL()
                        .replace(TiqrConstants.LOGIN_PAGE, TiqrConstants.TIQR_PAGE);
                String tiqrAction = StringUtils.isEmpty(request.getParameter(TiqrConstants.TIQR_ACTION))
                        ? TiqrConstants.TIQR_ACTION_AUTHENTICATION
                        : request.getParameter(TiqrConstants.TIQR_ACTION);
                String queryParams = FrameworkUtils.getQueryStringWithFrameworkContextId(context.getQueryParams(),
                        context.getCallerSessionKey(), context.getContextIdentifier());
                response.sendRedirect(response.encodeRedirectURL(enrollmentPage + ("?" + queryParams))
                        + TiqrConstants.AUTHENTICATORS + getName() + ":" + TiqrConstants.LOCAL + "&"
                        + TiqrConstants.TIQR_CLIENT_IP + "="
                        + authenticatorProperties.get(TiqrConstants.TIQR_CLIENT_IP) + "&"
                        + TiqrConstants.TIQR_CLIENT_PORT + "="
                        + authenticatorProperties.get(TiqrConstants.TIQR_CLIENT_PORT) + "&"
                        + TiqrConstants.TIQR_ACTION + "=" + tiqrAction + retryParam);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Error while retrieving properties. Authenticator Properties cannot be null");
                }
                throw new AuthenticationFailedException(
                        "Error while retrieving properties. Authenticator Properties cannot be null");
            }
        } catch (IOException e) {
            throw new AuthenticationFailedException("Exception while redirecting the page: " + e.getMessage(), e);
        }
    }

    /**
     * Get the configuration properties of UI
     */
    @Override
    public List<Property> getConfigurationProperties() {
        List<Property> configProperties = new ArrayList<Property>();

        Property clientIP = new Property();
        clientIP.setName(TiqrConstants.TIQR_CLIENT_IP);
        clientIP.setDisplayName("Client IP");
        clientIP.setRequired(true);
        clientIP.setDescription("Enter the IP address of the tiqr client");
        configProperties.add(clientIP);

        Property clientPort = new Property();
        clientPort.setName(TiqrConstants.TIQR_CLIENT_PORT);
        clientPort.setDisplayName("Client Port");
        clientPort.setRequired(true);
        clientPort.setDescription("Enter the port of the tiqr client");
        configProperties.add(clientPort);

        Property waitTime = new Property();
        waitTime.setName(TiqrConstants.TIQR_WAIT_TIME);
        waitTime.setDisplayName("Wait Time");
        waitTime.setDescription("Period of waiting to terminate the authentication (in seconds)");
        configProperties.add(waitTime);
        return configProperties;
    }

    /**
     * Process the response of the Tiqr end-point
     */
    @Override
    protected void processAuthenticationResponse(HttpServletRequest request, HttpServletResponse response,
            AuthenticationContext context) throws AuthenticationFailedException {
        try {
            if (request.getParameter(TiqrConstants.TIQR_ACTION).equals(TiqrConstants.TIQR_ACTION_ENROLLMENT)
                    && (StringUtils.isEmpty(request.getParameter(TiqrConstants.ENROLL_USERID))
                            || StringUtils.isEmpty(request.getParameter(TiqrConstants.ENROLL_DISPLAYNAME))
                            || StringUtils.isEmpty(request.getParameter(TiqrConstants.AUTH_USERNAME))
                            || StringUtils.isEmpty(request.getParameter(TiqrConstants.AUTH_PASSWORD)))) {
                log.error("Required fields cannot not be null");
                throw new InvalidCredentialsException("Required fields cannot not be null");
            } else if (request.getParameter(TiqrConstants.TIQR_ACTION).equals(TiqrConstants.TIQR_ACTION_ENROLLMENT)
                    && StringUtils.isEmpty(request.getParameter(TiqrConstants.ENROLL_SESSIONID))) {
                log.error(TiqrConstants.UNABLE_TO_CONNECT + ":" + TiqrConstants.SESSIONID_NULL);
                throw new AuthenticationFailedException(
                        TiqrConstants.UNABLE_TO_CONNECT + ":" + TiqrConstants.SESSIONID_NULL);
            }
            Map<String, String> authenticatorProperties = context.getAuthenticatorProperties();
            String tiqrEP = getTiqrEndpoint(authenticatorProperties);
            String userId = "";
            int status = 0;
            int retry = 0;
            int retryInterval = Integer.parseInt(TiqrConstants.RETRYINTERVAL);
            int maxCount = 120;
            int waitTime = StringUtils.isEmpty(authenticatorProperties.get(TiqrConstants.TIQR_WAIT_TIME)) ? maxCount
                    : Integer.parseInt(authenticatorProperties.get(TiqrConstants.TIQR_WAIT_TIME));
            int retryCount = maxCount > waitTime ? waitTime : maxCount;
            if (request.getParameter(TiqrConstants.TIQR_ACTION).equals(TiqrConstants.TIQR_ACTION_AUTHENTICATION)) {
                String urlToCheckAuthentication = tiqrEP + TiqrConstants.TIQR_CLIENT_AUTHENTICATE_URL
                        + request.getParameter(TiqrConstants.TIQR_CLIENT_AUTH_STATE) + "&"
                        + TiqrConstants.ENROLL_SESSIONID + "="
                        + request.getParameter(TiqrConstants.ENROLL_SESSIONID);
                while (retry < retryCount) {
                    String checkStatusResponse = sendRESTCall(urlToCheckAuthentication, "",
                            "action=getAuthenticatedUser", TiqrConstants.HTTP_POST);
                    if (checkStatusResponse.startsWith(TiqrConstants.FAILED)) {
                        throw new AuthenticationFailedException("Unable to connect to the Tiqr: "
                                + checkStatusResponse.replace(TiqrConstants.FAILED, ""));
                    }
                    if (checkStatusResponse.contains("authenticatedUser")) {
                        userId = checkStatusResponse
                                .substring(checkStatusResponse.indexOf("name=\"authenticatedUser\" value=\""),
                                        checkStatusResponse.indexOf("\" id=\"authenticatedUser\"/>"))
                                .replace("name=\"authenticatedUser\" value=\"", "").trim();
                        status = StringUtils.isEmpty(userId)
                                ? Integer.parseInt(TiqrConstants.ENROLLMENT_FAILED_STATUS)
                                : Integer.parseInt(TiqrConstants.ENROLLMENT_SUCCESS_STATUS);
                        if (status == Integer.parseInt(TiqrConstants.ENROLLMENT_SUCCESS_STATUS)) {
                            if (log.isDebugEnabled()) {
                                log.debug("Successfully authenticated the user associated with the User ID:"
                                        + userId);
                            }
                            break;
                        }
                    }
                    Thread.sleep(retryInterval);
                    retry++;
                    if (retry == retryCount) {
                        log.error("Authentication timed out.");
                        break;
                    }
                }
                if (status == Integer.parseInt(TiqrConstants.ENROLLMENT_SUCCESS_STATUS)) {
                    String userName = getAssociatedUsername(context, userId);
                    if (StringUtils.isEmpty(userName)) {
                        throw new AuthenticationFailedException(
                                "This tiqr user is not associated with " + "any authenticated IS user");
                    } else {
                        if (log.isDebugEnabled()) {
                            log.debug("The associated username for this Tiqr ID is :" + userName);
                        }
                    }
                }
            } else {
                String username = request.getParameter(TiqrConstants.AUTH_USERNAME);
                String password = request.getParameter(TiqrConstants.AUTH_PASSWORD);
                int tenantId = IdentityTenantUtil.getTenantIdOfUser(username);
                UserStoreManager userStoreManager = (UserStoreManager) TiqrAuthenticatorServiceComponent
                        .getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
                boolean isAuthenticated = userStoreManager
                        .authenticate(MultitenantUtils.getTenantAwareUsername(username), password);
                if (!isAuthenticated) {
                    log.error(TiqrConstants.INVALID_USERNAME_PASSWORD_ERROR);
                    throw new AuthenticationFailedException(TiqrConstants.INVALID_USERNAME_PASSWORD_ERROR);
                }
                userId = request.getParameter(TiqrConstants.ENROLL_USERID);
                String urlToCheckEntrolment = tiqrEP + TiqrConstants.TIQR_CLIENT_NEW_USER_URL
                        + request.getParameter(TiqrConstants.TIQR_CLIENT_AUTH_STATE) + "&"
                        + TiqrConstants.ENROLL_SESSIONID + "="
                        + request.getParameter(TiqrConstants.ENROLL_SESSIONID);
                while (retry < retryCount) {
                    String checkStatusResponse = sendRESTCall(urlToCheckEntrolment, "", "action=getStatus",
                            TiqrConstants.HTTP_POST);
                    if (checkStatusResponse.startsWith(TiqrConstants.FAILED)) {
                        throw new AuthenticationFailedException("Unable to connect to the Tiqr: "
                                + checkStatusResponse.replace(TiqrConstants.FAILED, ""));
                    }
                    if (checkStatusResponse.contains("enrollmentStatus")) {
                        status = Integer.parseInt(checkStatusResponse
                                .substring(checkStatusResponse.indexOf("name=\"enrollmentStatus\" value=\""),
                                        checkStatusResponse.indexOf("\" id=\"enrollmentStatus\"/>"))
                                .replace("name=\"enrollmentStatus\" value=\"", "").trim());
                        if (log.isDebugEnabled()) {
                            log.debug("Enrolment status: " + status);
                        }
                    }
                    if (status == Integer.parseInt(TiqrConstants.ENROLLMENT_SUCCESS_STATUS)) {
                        if (log.isDebugEnabled()) {
                            log.debug("Successfully enrolled the user with User ID:"
                                    + request.getParameter(TiqrConstants.ENROLL_USERID) + "and Display Name:"
                                    + request.getParameter(TiqrConstants.ENROLL_DISPLAYNAME));
                        }
                        break;
                    }
                    Thread.sleep(retryInterval);
                    retry++;
                    if (retry == retryCount) {
                        log.error("Enrolment timed out.");
                        break;
                    }
                }
                if (status == Integer.parseInt(TiqrConstants.ENROLLMENT_SUCCESS_STATUS)) {
                    associateFederatedIdToLocalUsername(request, context,
                            getFederateAuthenticatedUser(context, userId));
                }
            }
            if (status == Integer.parseInt(TiqrConstants.ENROLLMENT_SUCCESS_STATUS)) {
                setSubject(context, getFederateAuthenticatedUser(context, userId));
            } else {
                throw new AuthenticationFailedException(
                        request.getParameter(TiqrConstants.TIQR_ACTION) + " failed");
            }
        } catch (NumberFormatException e) {
            log.error(request.getParameter(TiqrConstants.TIQR_ACTION) + " failed: " + e.getMessage(), e);
            throw new AuthenticationFailedException(
                    request.getParameter(TiqrConstants.TIQR_ACTION) + " failed: " + e.getMessage(), e);
        } catch (InterruptedException e) {
            log.error("Interruption occured while getting the" + request.getParameter(TiqrConstants.TIQR_ACTION)
                    + " status" + e.getMessage(), e);
            throw new AuthenticationFailedException("Interruption occured while getting the"
                    + request.getParameter(TiqrConstants.TIQR_ACTION) + " status" + e.getMessage(), e);
        } catch (IndexOutOfBoundsException e) {
            log.error("Error while getting the " + request.getParameter(TiqrConstants.TIQR_ACTION) + " status"
                    + e.getMessage(), e);
            throw new AuthenticationFailedException("Error while getting the "
                    + request.getParameter(TiqrConstants.TIQR_ACTION) + " status" + e.getMessage(), e);
        } catch (ApplicationAuthenticatorException e) {
            log.error("Unable to set the subject: " + e.getMessage(), e);
            throw new AuthenticationFailedException("Unable to set the subject: " + e.getMessage(), e);
        } catch (UserProfileException e) {
            throw new InvalidCredentialsException("Unable to access the user profile: " + e.getMessage(), e);
        } catch (UserStoreException e) {
            log.error("Unable to get the user store manager: " + e.getMessage(), e);
            throw new AuthenticationFailedException("Unable to get the user store manager: " + e.getMessage(), e);
        }
    }

    /**
     * Send REST call
     */
    private String sendRESTCall(String url, String urlParameters, String formParameters, String httpMethod) {
        String line;
        StringBuilder responseString = new StringBuilder();
        HttpURLConnection connection = null;
        try {
            URL tiqrEP = new URL(url + urlParameters);
            connection = (HttpURLConnection) tiqrEP.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestMethod(httpMethod);
            connection.setRequestProperty(TiqrConstants.HTTP_CONTENT_TYPE, TiqrConstants.HTTP_CONTENT_TYPE_XWFUE);
            if (httpMethod.toUpperCase().equals(TiqrConstants.HTTP_POST)) {
                OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(),
                        TiqrConstants.CHARSET);
                writer.write(formParameters);
                writer.close();
            }
            if (connection.getResponseCode() == 200) {
                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                while ((line = br.readLine()) != null) {
                    responseString.append(line);
                }
                br.close();
            } else {
                return TiqrConstants.FAILED + TiqrConstants.REQUEST_FAILED;
            }
        } catch (ProtocolException e) {
            if (log.isDebugEnabled()) {
                log.debug(TiqrConstants.FAILED + e.getMessage());
            }
            return TiqrConstants.FAILED + e.getMessage();
        } catch (MalformedURLException e) {
            if (log.isDebugEnabled()) {
                log.debug(TiqrConstants.FAILED + e.getMessage());
            }
            return TiqrConstants.FAILED + e.getMessage();
        } catch (IOException e) {
            if (log.isDebugEnabled()) {
                log.debug(TiqrConstants.FAILED + e.getMessage());
            }
            return TiqrConstants.FAILED + e.getMessage();
        } finally {
            connection.disconnect();
        }
        return responseString.toString();
    }

    /**
     * Get the tiqr end-point
     */
    protected String getTiqrEndpoint(Map<String, String> authenticatorProperties) {
        return TiqrConstants.PROTOCOL + authenticatorProperties.get(TiqrConstants.TIQR_CLIENT_IP) + ":"
                + authenticatorProperties.get(TiqrConstants.TIQR_CLIENT_PORT);
    }

    /**
     * Get the friendly name of the Authenticator
     */
    @Override
    public String getFriendlyName() {
        return TiqrConstants.AUTHENTICATOR_FRIENDLY_NAME;
    }

    /**
     * Get the name of the Authenticator
     */
    @Override
    public String getName() {
        return TiqrConstants.AUTHENTICATOR_NAME;
    }

    @Override
    protected boolean retryAuthenticationEnabled() {
        return true;
    }

    /**
     * Get the Context identifier sent with the request.
     */
    public String getContextIdentifier(HttpServletRequest request) {
        return request.getParameter("sessionDataKey");
    }

    private AuthenticatedUser getFederateAuthenticatedUser(AuthenticationContext context,
            String authenticatedUserId) throws ApplicationAuthenticatorException {
        if (StringUtils.isEmpty(authenticatedUserId)) {
            throw new ApplicationAuthenticatorException("Authenticated user identifier is empty");
        }
        AuthenticatedUser authenticatedUser = AuthenticatedUser
                .createFederateAuthenticatedUserFromSubjectIdentifier(authenticatedUserId);
        authenticatedUser.setUserName(authenticatedUserId);
        if (log.isDebugEnabled()) {
            log.debug("The authenticated subject identifier :"
                    + authenticatedUser.getAuthenticatedSubjectIdentifier());
        }
        return authenticatedUser;
    }

    private void setSubject(AuthenticationContext context, AuthenticatedUser authenticatedUser) {
        context.setSubject(authenticatedUser);
        SequenceConfig seqConfig = context.getSequenceConfig();
        seqConfig.setAuthenticatedUser(authenticatedUser);
    }

    private void associateFederatedIdToLocalUsername(HttpServletRequest request, AuthenticationContext context,
            AuthenticatedUser authenticatedUser) throws UserProfileException {
        String authenticatedLocalUsername = request.getParameter(TiqrConstants.AUTH_USERNAME);
        StepConfig stepConfig = null;

        for (int i = 1; i <= context.getSequenceConfig().getStepMap().size(); i++) {
            stepConfig = context.getSequenceConfig().getStepMap().get(i);
            for (int j = 0; j < stepConfig.getAuthenticatorList().size(); j++) {
                if (stepConfig.getAuthenticatorList().get(j).getName().equals(getName())) {
                    try {
                        String idpName = FrameworkConstants.LOCAL_IDP_NAME;
                        String originalExternalIdpSubjectValueForThisStep = authenticatedUser
                                .getAuthenticatedSubjectIdentifier();
                        idpName = context.getExternalIdP().getIdPName();
                        stepConfig.setAuthenticatedIdP(idpName);
                        associateID(idpName, originalExternalIdpSubjectValueForThisStep,
                                authenticatedLocalUsername);
                        stepConfig.setAuthenticatedUser(authenticatedUser);
                        context.getSequenceConfig().getStepMap().put(i, stepConfig);
                    } catch (UserProfileException e) {
                        throw new UserProfileException("Unable to continue with the federated ID ("
                                + authenticatedUser.getAuthenticatedSubjectIdentifier() + "): " + e.getMessage(),
                                e);
                    }
                    break;
                }
            }
        }
    }

    private String getAssociatedUsername(AuthenticationContext context, String userId) throws UserProfileException {
        StepConfig stepConfig = null;
        String associatedUserName = "";
        for (int i = 1; i <= context.getSequenceConfig().getStepMap().size(); i++) {
            stepConfig = context.getSequenceConfig().getStepMap().get(i);
            for (int j = 0; j < stepConfig.getAuthenticatorList().size(); j++) {
                if (stepConfig.getAuthenticatorList().get(j).getName().equals(getName())) {
                    try {
                        String idpName = FrameworkConstants.LOCAL_IDP_NAME;
                        idpName = context.getExternalIdP().getIdPName();
                        stepConfig.setAuthenticatedIdP(idpName);
                        UserProfileAdmin userProfileAdmin = UserProfileAdmin.getInstance();
                        associatedUserName = userProfileAdmin.getNameAssociatedWith(idpName, userId);
                    } catch (UserProfileException e) {
                        throw new UserProfileException("Unable to get the username associated with "
                                + "the federated ID (" + userId + "): " + e.getMessage(), e);
                    }
                    break;
                }
            }
        }
        return associatedUserName;
    }

    private void associateID(String idpID, String associatedID, String userName) throws UserProfileException {
        Connection connection = IdentityDatabaseUtil.getDBConnection();
        PreparedStatement prepStmt = null;
        String sql = null;
        int tenantID = CarbonContext.getThreadLocalCarbonContext().getTenantId();
        String tenantAwareUsername = MultitenantUtils.getTenantAwareUsername(userName);
        String domainName = getDomainName(tenantAwareUsername);
        tenantAwareUsername = getUsernameWithoutDomain(tenantAwareUsername);

        try {
            sql = "INSERT INTO IDN_ASSOCIATED_ID (TENANT_ID, IDP_ID, IDP_USER_ID, DOMAIN_NAME, USER_NAME) VALUES "
                    + "(? , (SELECT ID FROM IDP WHERE NAME = ? AND TENANT_ID = ? ), ? , ?, ?)";
            prepStmt = connection.prepareStatement(sql);
            prepStmt.setInt(1, tenantID);
            prepStmt.setString(2, idpID);
            prepStmt.setInt(3, tenantID);
            prepStmt.setString(4, associatedID);
            prepStmt.setString(5, domainName);
            prepStmt.setString(6, tenantAwareUsername);
            prepStmt.execute();
            connection.commit();
        } catch (SQLException e) {
            log.error("Error occurred while persisting the federated user ID", e);
            throw new UserProfileException("Error occurred while persisting the federated user ID", e);
        } finally {
            IdentityDatabaseUtil.closeAllConnections(connection, (ResultSet) null, prepStmt);
        }
    }

    private static String getDomainName(String username) {
        int index = username.indexOf("/");
        return index < 0 ? "PRIMARY" : username.substring(0, index);
    }

    private static String getUsernameWithoutDomain(String username) {
        int index = username.indexOf("/");
        return index < 0 ? username : username.substring(index + 1, username.length());
    }
}