Package org.wso2.carbon.identity.sso.saml.processors

Source Code of org.wso2.carbon.identity.sso.saml.processors.AuthnRequestProcessor

/*
*  Copyright (c) 2005-2010, 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.sso.saml.processors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opensaml.saml2.core.Response;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.core.util.AnonymousSessionUtil;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO;
import org.wso2.carbon.identity.core.persistence.IdentityPersistenceManager;
import org.wso2.carbon.identity.sso.saml.SAMLSSOConstants;
import org.wso2.carbon.identity.sso.saml.SSOServiceProviderConfigManager;
import org.wso2.carbon.identity.sso.saml.builders.ErrorResponseBuilder;
import org.wso2.carbon.identity.sso.saml.builders.ResponseBuilder;
import org.wso2.carbon.identity.sso.saml.dto.SAMLSSOAuthnReqDTO;
import org.wso2.carbon.identity.sso.saml.dto.SAMLSSOReqValidationResponseDTO;
import org.wso2.carbon.identity.sso.saml.dto.SAMLSSORespDTO;
import org.wso2.carbon.identity.sso.saml.session.SSOSessionPersistenceManager;
import org.wso2.carbon.identity.sso.saml.session.SessionInfoData;
import org.wso2.carbon.identity.sso.saml.util.SAMLSSOUtil;
import org.wso2.carbon.user.core.UserRealm;
import org.wso2.carbon.user.core.UserStoreManager;
import org.wso2.carbon.user.core.util.UserCoreUtil;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;

public class AuthnRequestProcessor {

    private static Log log = LogFactory.getLog(AuthnRequestProcessor.class);

    public SAMLSSORespDTO process(SAMLSSOAuthnReqDTO authnReqDTO, String sessionId,
                                  boolean isAuthencated, String authMode)
            throws Exception {
        try {

            //validate issuer info.
            if (!validateIssuer(authnReqDTO)) {
                log.warn("Issuer details are not valid. Issuer details should be registered in advance");
                return buildErrorResponse(authnReqDTO.getId(), SAMLSSOConstants.StatusCodes.REQUESTOR_ERROR,
                        "Issuer details are not valid. Issuer details should be registered in advance");
            }

            // validate the signature
            if (authnReqDTO.getCertAlias() != null) {
                boolean isSignatureValid = SAMLSSOUtil.validateAssertionSignature(authnReqDTO.getAssertionString(),
                                                                      authnReqDTO.getCertAlias(),
                                                                      MultitenantUtils.getTenantDomain(authnReqDTO.getUsername()));
                if (!isSignatureValid) {
                    log.warn("Signature Validation Failed for the SAML Assertion.");
                    return buildErrorResponse(authnReqDTO.getId(), SAMLSSOConstants.StatusCodes.REQUESTOR_ERROR,
                                              "Signature Validation Failed for the SAML Assertion.");
                }
            }

            //if subject is specified in Auth.Request only that user should be allowed to logged-in
            if (authnReqDTO.getSubject() != null && authnReqDTO.getUsername() != null) {
                if (!authnReqDTO.getUsername().equals(authnReqDTO.getSubject())) {
                    log.warn("Provided username does not match with the requested subject");
                    return buildErrorResponse(authnReqDTO.getId(), SAMLSSOConstants.StatusCodes.AUTHN_FAILURE,
                            "Provided username does not match with the requested subject");
                }
            }

            //persist the session
            SSOSessionPersistenceManager sessionPersistenceManager = SSOSessionPersistenceManager
                    .getPersistenceManager();

            //authenticate the user, if required
            if (!isAuthencated && authMode.equals(SAMLSSOConstants.AuthnModes.USERNAME_PASSWORD)) {
                if (!authenticate(authnReqDTO.getUsername(), authnReqDTO.getPassword())) {
                    log.warn("Authentication Failure, invalid username or password.");
                    SAMLSSORespDTO errorResp = buildErrorResponse(authnReqDTO.getId(), SAMLSSOConstants.StatusCodes.AUTHN_FAILURE,
                            "Authentication Failure, invalid username or password.");
                    errorResp.setLoginPageURL(authnReqDTO.getLoginPageURL());
                    return errorResp;
                }
                SAMLSSOServiceProviderDO spDO = new SAMLSSOServiceProviderDO();
                spDO.setIssuer(authnReqDTO.getIssuer());
                spDO.setAssertionConsumerUrl(authnReqDTO.getAssertionConsumerURL());
                spDO.setCertAlias(authnReqDTO.getCertAlias());
                spDO.setLogoutURL(authnReqDTO.getLogoutURL());
                sessionPersistenceManager.persistSession(sessionId, authnReqDTO.getUsername(),
                                                         spDO, authnReqDTO.getRpSessionId());
            }

            if (isAuthencated && authMode.equals(SAMLSSOConstants.AuthnModes.USERNAME_PASSWORD)) {
                SessionInfoData sessionInfo = sessionPersistenceManager.getSessionInfo(sessionId);
                authnReqDTO.setUsername(sessionInfo.getSubject());
                sessionPersistenceManager.persistSession(sessionId, authnReqDTO.getIssuer(),
                        authnReqDTO.getAssertionConsumerURL(), authnReqDTO.getRpSessionId());
            }

            if(isAuthencated && authMode.equals(SAMLSSOConstants.AuthnModes.OPENID)){
                SAMLSSOServiceProviderDO spDO = new SAMLSSOServiceProviderDO();
                spDO.setIssuer(authnReqDTO.getIssuer());
                spDO.setAssertionConsumerUrl(authnReqDTO.getAssertionConsumerURL());
                spDO.setCertAlias(authnReqDTO.getCertAlias());
                spDO.setLogoutURL(authnReqDTO.getLogoutURL());
                sessionPersistenceManager.persistSession(sessionId, authnReqDTO.getUsername(),
                                                         spDO, authnReqDTO.getRpSessionId());
            }

            //Build the response for the successful scenario
            ResponseBuilder respBuilder = new ResponseBuilder();
            Response response = respBuilder.buildResponse(authnReqDTO, sessionId);
            SAMLSSORespDTO samlssoRespDTO = new SAMLSSORespDTO();
            samlssoRespDTO.setRespString(SAMLSSOUtil.encode(SAMLSSOUtil.marshall(response)));
            samlssoRespDTO.setSessionEstablished(true);
            samlssoRespDTO.setAssertionConsumerURL(authnReqDTO.getAssertionConsumerURL());
            samlssoRespDTO.setLoginPageURL(authnReqDTO.getLoginPageURL());
            return samlssoRespDTO;

        } catch (Exception e) {
            log.error("Error processing the authentication request",e);
            SAMLSSORespDTO errorResp =  buildErrorResponse(authnReqDTO.getId(), SAMLSSOConstants.StatusCodes.AUTHN_FAILURE,
                            "Authentication Failure, invalid username or password.");
            errorResp.setLoginPageURL(authnReqDTO.getLoginPageURL());
            return errorResp;
        }
    }

    public SAMLSSOReqValidationResponseDTO process(SAMLSSOReqValidationResponseDTO valiationDTO, String sessionId, String rpSessionId, String authMode)
            throws Exception {
        SAMLSSOAuthnReqDTO authReqDTO = new SAMLSSOAuthnReqDTO();
        authReqDTO.setIssuer(valiationDTO.getIssuer());
        authReqDTO.setAssertionConsumerURL(valiationDTO.getAssertionConsumerURL());
        authReqDTO.setSubject(valiationDTO.getSubject());
        authReqDTO.setId(valiationDTO.getId());
        authReqDTO.setRpSessionId(rpSessionId);
        authReqDTO.setAssertionString(valiationDTO.getAssertionString());

        if (authMode.equals(SAMLSSOConstants.AuthnModes.USERNAME_PASSWORD)) {
            //Set the username in the SAMLSSOAuthnReqDTO
            SSOSessionPersistenceManager sessionPersistenceManager = SSOSessionPersistenceManager
                    .getPersistenceManager();
            SessionInfoData sessionInfo = sessionPersistenceManager.getSessionInfo(sessionId);
            authReqDTO.setUsername(sessionInfo.getSubject());
        }
        else{
            authReqDTO.setUsername(valiationDTO.getSubject());
        }

        SAMLSSOReqValidationResponseDTO responseDTO = new SAMLSSOReqValidationResponseDTO();
        SAMLSSORespDTO respDTO = process(authReqDTO, sessionId, true, authMode);
        responseDTO.setValid(true);
        responseDTO.setResponse(respDTO.getRespString());
        responseDTO.setAssertionConsumerURL(respDTO.getAssertionConsumerURL());
        responseDTO.setLoginPageURL(respDTO.getLoginPageURL());
        return responseDTO;
    }

    private SAMLSSORespDTO buildErrorResponse(String id, String status, String statMsg) throws Exception {
        SAMLSSORespDTO samlSSORespDTO = new SAMLSSORespDTO();
        ErrorResponseBuilder errRespBuilder = new ErrorResponseBuilder();
        Response resp = errRespBuilder.buildResponse(id, status, statMsg);
        samlSSORespDTO.setRespString(SAMLSSOUtil.encode(SAMLSSOUtil.marshall(resp)));
        samlSSORespDTO.setSessionEstablished(false);
        return samlSSORespDTO;
    }

    private boolean authenticate(String username, String password) throws IdentityException {
        boolean isAuthenticated = false;
        try {
            UserRealm realm = AnonymousSessionUtil.getRealmByUserName(
                    SAMLSSOUtil.getRegistryService(), SAMLSSOUtil.getRealmService(), username);

            if(realm == null){
                log.warn("Realm creation failed. Tenant may be inactive or invalid.");
                return false;
            }
           
            UserStoreManager userStoreManager = realm.getUserStoreManager();

//            //update the permission tree before authentication
//            String tenantDomain = MultitenantUtils.getTenantDomain(username);
//            int tenantId = SAMLSSOUtil.getRealmService().getTenantManager().getTenantId(tenantDomain);
//            PermissionUpdateUtil.updatePermissionTree(tenantId);

            // Check the authentication
            isAuthenticated = userStoreManager.authenticate(UserCoreUtil.getTenantLessUsername(username), password);
            if(!isAuthenticated){
                if (log.isDebugEnabled()) {
                    log.debug("user authentication failed due to invalid credentials.");
                }
                return false;
            }

            // Check the authorization
            boolean isAuthorized = realm.getAuthorizationManager().
                    isUserAuthorized(UserCoreUtil.getTenantLessUsername(username), "/permission/admin/login", CarbonConstants.UI_PERMISSION_ACTION);
            if(!isAuthorized){
                if(log.isDebugEnabled()){
                    log.debug("Authorization Failure when performing log-in action");
                }
                return false;
            }
            if (log.isDebugEnabled()) {
                    log.debug("User is successfully authenticated.");
            }
            return true;
        } catch (Exception e) {
            log.error("Error obtaining user realm for authenticating the user", e);
            throw new IdentityException("Error obtaining user realm for authenticating the user", e);
        }
    }

    private boolean validateIssuer(SAMLSSOAuthnReqDTO authReqDTO) throws IdentityException {

        try {
            SSOServiceProviderConfigManager spConfigManager = SSOServiceProviderConfigManager.getInstance();
            SAMLSSOServiceProviderDO spDO = spConfigManager.getServiceProvider(authReqDTO.getIssuer());
            if (spDO == null) {
                IdentityPersistenceManager persistenceManager = IdentityPersistenceManager.getPersistanceManager();
                spDO = persistenceManager.getServiceProvider(
                        AnonymousSessionUtil.getSystemRegistryByUserName(SAMLSSOUtil.getRegistryService(),
                                SAMLSSOUtil.getRealmService(), authReqDTO.getUsername()), authReqDTO.getIssuer());
            }

            //Invalid issuer
            if (spDO == null) {
                return false;
            }

            //give more priority to the Assrtn Consumer URL if specified in the Auth. Req
            if (authReqDTO.getAssertionConsumerURL() == null) {
                authReqDTO.setAssertionConsumerURL(spDO.getAssertionConsumerUrl());
            }

            authReqDTO.setLoginPageURL(spDO.getLoginPageURL());
            authReqDTO.setCertAlias(spDO.getCertAlias());
            authReqDTO.setUseFullyQualifiedUsernameAsSubject(spDO.isUseFullyQualifiedUsername());
            authReqDTO.setDoSingleLogout(spDO.isDoSingleLogout());
            authReqDTO.setLogoutURL(spDO.getLogoutURL());
            authReqDTO.setDoSignAssertions(spDO.isDoSignAssertions());
            return true;

        } catch (Exception e) {
            log.error("Error validating the issuer", e);
            throw new IdentityException("Error validating the issuer", e);
        }

    }
}
TOP

Related Classes of org.wso2.carbon.identity.sso.saml.processors.AuthnRequestProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.