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

Source Code of org.wso2.carbon.identity.sso.saml.ui.SAMLSSOProvider

/*
*  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.ui;

import org.apache.axis2.context.ConfigurationContext;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.identity.sso.saml.stub.IdentityException;
import org.wso2.carbon.identity.sso.saml.stub.types.SAMLSSOAuthnReqDTO;
import org.wso2.carbon.identity.sso.saml.stub.types.SAMLSSOReqValidationResponseDTO;
import org.wso2.carbon.identity.sso.saml.stub.types.SAMLSSORespDTO;
import org.wso2.carbon.identity.sso.saml.ui.client.SAMLSSOServiceClient;
import org.wso2.carbon.identity.sso.saml.ui.logout.LogoutRequestSender;
import org.wso2.carbon.identity.sso.saml.ui.session.mgt.FESessionBean;
import org.wso2.carbon.identity.sso.saml.ui.session.mgt.FESessionManager;
import org.wso2.carbon.ui.CarbonUIUtil;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SAMLSSOProvider extends HttpServlet {
   
    /**
     * session timeout happens in 10 hours
     */
    private static final int SSO_SESSION_EXPIRE = 36000;

    @Override
    protected void doGet(HttpServletRequest httpServletRequest,
                         HttpServletResponse httpServletResponse)
            throws ServletException, IOException {
        doPost(httpServletRequest, httpServletResponse);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String username = request.getParameter(SAMLSSOProviderConstants.USERNAME);
        String password = request.getParameter(SAMLSSOProviderConstants.PASSWORD);
        HttpSession session = request.getSession();

        // Use sessionID as the tokenID, if cookie is not set.
        String ssoTokenID = session.getId();
        Cookie tokenCookie = getSSOTokenCookie(request);
        if (tokenCookie != null) {
            ssoTokenID = tokenCookie.getValue();
        }

        String serverURL = CarbonUIUtil.getServerURL(session.getServletContext(), session);
        ConfigurationContext configContext = (ConfigurationContext) session.getServletContext()
                .getAttribute(CarbonConstants.CONFIGURATION_CONTEXT);
        SAMLSSOServiceClient ssoServiceClient = new SAMLSSOServiceClient(serverURL, configContext);

        try {
            if (username == null && password == null) { // First request without credentials. Should redirect  to login page
                String samlRequest = request.getParameter("SAMLRequest");
                String authMode = SAMLSSOProviderConstants.AuthnModes.USERNAME_PASSWORD;
                if(request.getParameter("authMode") != null &&
                   SAMLSSOProviderConstants.AuthnModes.OPENID.equals(request.getParameter("authMode"))){
                    authMode = SAMLSSOProviderConstants.AuthnModes.OPENID;
                }
                String relayState = request.getParameter(SAMLSSOProviderConstants.RELAY_STATE);
                if (samlRequest != null) { // this is a login request
                    handleSAMLRequest(request, response,
                                      session, ssoTokenID, ssoServiceClient, samlRequest, relayState, authMode);
                } else { // Non-SAML request are assumed to be logout  requests
                    handleLogout(request, response);
                }
            } else // Request coming from login page with username and password
                handleRequestFromLoginPage(request, response,
                                           username, password, ssoTokenID,
                                           ssoServiceClient);
            }
        } catch (IdentityException e) { // in case of an error, redirect them to notifications page with an error msg.
            FESessionManager sessionManager = FESessionManager.getInstance();
            String authSessionID = sessionManager.addNewSession(new FESessionBean("Server Error", "Please try again later."));
            response.sendRedirect(getAdminConsoleURL(request) + "sso-saml/notification_page.jsp?" +
                                  SAMLSSOProviderConstants.FE_SESSION_KEY + "=" + authSessionID);
        }
    }

    private void handleRequestFromLoginPage(HttpServletRequest httpServletRequest,
                                            HttpServletResponse httpServletResponse,
                                            String username, String password,
                                            String ssoTokenID,
                                            SAMLSSOServiceClient ssoServiceClient)
            throws IdentityException, IOException {

        FESessionManager sessionManager = FESessionManager.getInstance();
        String authSessionID = httpServletRequest.getParameter(SAMLSSOProviderConstants.FE_SESSION_KEY);
        FESessionBean sessionBean = sessionManager.getFESessionBean(authSessionID);
        SAMLSSOReqValidationResponseDTO validationResponseDTO = null;
        if (sessionBean != null) {
            if (sessionBean.getSessionBean() instanceof SAMLSSOReqValidationResponseDTO) {
                validationResponseDTO = (SAMLSSOReqValidationResponseDTO) sessionBean.getSessionBean();
            }
        }
        else{
            String errorSessionId = sessionManager.addNewSession(new FESessionBean("This authenticated session is expired.", "Please sign-in again."));
            httpServletResponse.sendRedirect(getAdminConsoleURL(httpServletRequest) + "sso-saml/notification_page.jsp?" +
                                  SAMLSSOProviderConstants.FE_SESSION_KEY + "=" + errorSessionId);
            return;
        }
        // Create SAMLSSOAuthnReqDTO using a SAMLSSOReqValidationResponseDTO
        SAMLSSOAuthnReqDTO authnReqDTO = new SAMLSSOAuthnReqDTO();
        authnReqDTO.setAssertionConsumerURL(validationResponseDTO.getAssertionConsumerURL());
        authnReqDTO.setId(validationResponseDTO.getId());
        authnReqDTO.setIssuer(validationResponseDTO.getIssuer());
        authnReqDTO.setPassword(password);
        authnReqDTO.setUsername(username);
        authnReqDTO.setSubject(validationResponseDTO.getSubject());
        authnReqDTO.setRpSessionId(validationResponseDTO.getRpSessionId());
        authnReqDTO.setAssertionString(validationResponseDTO.getAssertionString());

        // authenticate the user
        SAMLSSORespDTO authRespDTO = ssoServiceClient.authenticate(authnReqDTO, ssoTokenID);

        if (authRespDTO.getSessionEstablished()) {  // authentication is SUCCESSFUL
            storeSSOTokenCookie(ssoTokenID, httpServletRequest, httpServletResponse);
            String respSessionAuthID = sessionManager.addNewSession(new FESessionBean(authRespDTO, sessionBean.getRelayState()));
            sessionManager.removeSession(authSessionID);    // remove the SAMLSSORespDTO
            httpServletResponse.sendRedirect(getAdminConsoleURL(httpServletRequest) + "sso-saml/redirect_ajaxprocessor.jsp?" + SAMLSSOProviderConstants.FE_SESSION_KEY + "=" + respSessionAuthID);
        } else {    // authentication FAILURE
            validationResponseDTO.setValid(false);
            httpServletResponse.sendRedirect(calculateLoginPage(
                        getAdminConsoleURL(httpServletRequest), authRespDTO.getLoginPageURL())+ "?" + SAMLSSOProviderConstants.FE_SESSION_KEY + "=" + authSessionID);
        }
    }

    private void handleLogout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
            throws IdentityException, IOException {
        FESessionManager sessionManager = FESessionManager.getInstance();
        String sessionId = sessionManager.addNewSession(new FESessionBean("You have been successfully signed out."
                , "All the other authenticated sessions are terminated."));
        httpServletResponse.sendRedirect(getAdminConsoleURL(httpServletRequest) + "sso-saml/notification_page.jsp?" +
                                         SAMLSSOProviderConstants.FE_SESSION_KEY + "=" + sessionId);
    }

    private void handleSAMLRequest(HttpServletRequest httpServletRequest,
                                   HttpServletResponse httpServletResponse, HttpSession session,
                                   String ssoTokenID, SAMLSSOServiceClient ssoServiceClient,
                                   String samlRequest, String relayState, String authMode)
            throws IdentityException, IOException {
        String rpSessionId = httpServletRequest.getParameter(MultitenantConstants.SSO_AUTH_SESSION_ID);
        SAMLSSOReqValidationResponseDTO signInRespDTO = ssoServiceClient.validate(samlRequest, ssoTokenID, rpSessionId, authMode);
        FESessionManager sessionManager = FESessionManager.getInstance();
        // If it is a login request.
        if (!signInRespDTO.getLogOutReq()) {
            //  an authentication context has not been already established, redirect user to a login page.
            if (signInRespDTO.getValid() && signInRespDTO.getResponse() == null) {
                String sessionID = sessionManager.addNewSession(new FESessionBean(signInRespDTO, relayState));
                httpServletResponse.sendRedirect(calculateLoginPage(
                        getAdminConsoleURL(httpServletRequest), signInRespDTO.getLoginPageURL())+ "?" +
                                                 SAMLSSOProviderConstants.FE_SESSION_KEY + "=" + sessionID);

                // an auth. context has been already established. So redirect users back to ACS.
            } else if (signInRespDTO.getResponse() != null) {
                String sessionID = sessionManager.addNewSession(new FESessionBean(signInRespDTO, relayState));
                if(SAMLSSOProviderConstants.AuthnModes.OPENID.equals(authMode)){
                    storeSSOTokenCookie(ssoTokenID, httpServletRequest, httpServletResponse);
                }
                httpServletResponse.sendRedirect(getAdminConsoleURL(httpServletRequest) + "sso-saml/redirect_ajaxprocessor.jsp?" + SAMLSSOProviderConstants.FE_SESSION_KEY + "=" + sessionID);
            }
        } else {     // in case of a logout request
            String sessionID = sessionManager.addNewSession(new FESessionBean(signInRespDTO, relayState));
            LogoutRequestSender.getInstance().sendLogoutRequests(signInRespDTO.getLogoutRespDTO());
            httpServletResponse.sendRedirect(getAdminConsoleURL(httpServletRequest) + "sso-saml/redirect_ajaxprocessor.jsp?" + SAMLSSOProviderConstants.FE_SESSION_KEY + "=" + sessionID);
        }
    }

    private String getAdminConsoleURL(HttpServletRequest request) {
        String url = CarbonUIUtil.getAdminConsoleURL(request);
        if (url.indexOf("/samlsso") != -1) {
            url = url.replace("/samlsso", "");
        }
        return url;
    }

    private Cookie getSSOTokenCookie(HttpServletRequest req) {
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(SAMLSSOProviderConstants.SSO_TOKEN_ID)) {
                    return cookie;
                }
            }
        }
        return null;
    }

    private void storeSSOTokenCookie(String ssoTokenID, HttpServletRequest req,
                                     HttpServletResponse resp) {
        Cookie ssoTokenCookie = getSSOTokenCookie(req);
        if (ssoTokenCookie == null) {
            ssoTokenCookie = new Cookie(SAMLSSOProviderConstants.SSO_TOKEN_ID, ssoTokenID);
        }
        ssoTokenCookie.setMaxAge(SSO_SESSION_EXPIRE);
        resp.addCookie(ssoTokenCookie);
    }

    private String calculateLoginPage(String adminConsoleURL, String customLoginPage){
        if(customLoginPage != null){
            return adminConsoleURL + customLoginPage.trim();
        }
        else{
            return adminConsoleURL + "sso-saml/login.jsp";
        }
    }

}
TOP

Related Classes of org.wso2.carbon.identity.sso.saml.ui.SAMLSSOProvider

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.