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

Source Code of org.wso2.carbon.identity.sso.saml.ui.logout.LogoutRequestSender

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.wso2.carbon.identity.sso.saml.stub.types.SingleLogoutRequestDTO;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* This class is used to send logout requests to each and every session participant. It follows a fire and
* forget approach where the task of sending each and every logout request is submitted to a threadpool
* as a job. This class implements a singleton, because it is expensive to create thread pool for each
* and every object.
*/
public class LogoutRequestSender {

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

    private static ExecutorService threadPool = Executors.newFixedThreadPool(2);

    private static LogoutRequestSender instance = new LogoutRequestSender();

    /**
     * This class is used to model a single logout request that is being sent to a session participant.
     * It will send the logout req. to the session participant in its 'run' method when this job is
     * submitted to the thread pool.
     */
    private class LogoutReqSenderTask implements Runnable {

        private SingleLogoutRequestDTO logoutReqDTO;

        public LogoutReqSenderTask(SingleLogoutRequestDTO logoutReqDTO) {
            this.logoutReqDTO = logoutReqDTO;
        }

        public void run() {
            List<NameValuePair> logoutReqParams = new ArrayList<NameValuePair>();
            // set the logout request
            logoutReqParams.add(new BasicNameValuePair("SAMLRequest", logoutReqDTO.getLogoutResponse()));
            try {
                int port = derivePortFromAssertionConsumerURL(logoutReqDTO.getAssertionConsumerURL());
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(logoutReqParams, "UTF-8");
                HttpPost httpPost = new HttpPost(logoutReqDTO.getAssertionConsumerURL());
                httpPost.setEntity(entity);
                httpPost.addHeader("Cookie", "JSESSIONID=" + logoutReqDTO.getRpSessionId());
                TrustManager easyTrustManager = new X509TrustManager() {
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] x509Certificates,
                            String s)
                            throws java.security.cert.CertificateException {
                    }

                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] x509Certificates,
                            String s)
                            throws java.security.cert.CertificateException {
                    }

                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                };

                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, new TrustManager[]{easyTrustManager}, null);
                SSLSocketFactory sf = new SSLSocketFactory(sslContext);
                sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
                Scheme httpsScheme = new Scheme("https", sf, port);

                HttpClient httpClient = new DefaultHttpClient();
                httpClient.getConnectionManager().getSchemeRegistry().register(httpsScheme);
               
                // send the logout request as a POST
                HttpResponse response = httpClient.execute(httpPost);
                log.info("single logout request is sent to : " + logoutReqDTO.getAssertionConsumerURL() +
                         " is returned with " + response.getStatusLine().getStatusCode());
                if (log.isDebugEnabled()) {
                    log.debug("single logout request is sent to : " + logoutReqDTO.getAssertionConsumerURL() +
                              " is returned with " + response.getStatusLine().getStatusCode());
                }
            } catch (IOException e) {
                log.error("Error sending logout requests to : " +
                          logoutReqDTO.getAssertionConsumerURL(), e);
            } catch (GeneralSecurityException e) {
                log.error("Error registering the EasySSLProtocolSocketFactory", e);
            } catch (RuntimeException e) {
                log.error("Runtime exception occurred.", e);
            } catch (URISyntaxException e) {
                log.error("Error deriving port from the assertion consumer url", e);
            }
        }
    }

    /**
     * A private constructor since we are implementing a singleton here
     */
    private LogoutRequestSender() {

    }

    /**
     * getInstance method of LogoutRequestSender, as it is a singleton
     *
     * @return LogoutRequestSender instance
     */
    public static LogoutRequestSender getInstance() {
        return instance;
    }

    /**
     * takes an array of SingleLogoutRequestDTO objects, creates and submits each of them as a task
     * to the thread pool
     *
     * @param logoutReqs Array of SingleLogoutRequestDTO representing all the session participants
     */
    public void sendLogoutRequests(SingleLogoutRequestDTO[] logoutReqs) {
        if (logoutReqs == null) {
            return;
        }
        // For each logoutReq, create a new task and submit it to the thread pool.
        for (SingleLogoutRequestDTO reqDTO : logoutReqs) {
            threadPool.submit(new LogoutReqSenderTask(reqDTO));
            if (log.isDebugEnabled()) {
                log.debug("A logoutReqSenderTask is assigned to the thread pool");

            }
        }
    }

    /**
     * This method is used to derive the port from the assertion consumer URL.
     *
     * @param assertionConsumerURL Assertion Consumer URL
     * @return Port, if mentioned in the URL, or else 443 as the default value
     * @throws MalformedURLException when the ACS is malformed.
     */
    private int derivePortFromAssertionConsumerURL(String assertionConsumerURL)
            throws URISyntaxException {
        int port = 443;    // use 443 as the default port
        try {
            URI uri = new URI(assertionConsumerURL);
            if (uri.getPort() != -1) {    // if the port is mentioned in the URL
                port = uri.getPort();
            } else if ("http".equals(uri.getScheme())) {  // if it is using http
                port = 80;
            }
        } catch (URISyntaxException e) {
            log.error("Error deriving port from the assertion consumer url", e);
            throw e;
        }
        return port;
    }


}
TOP

Related Classes of org.wso2.carbon.identity.sso.saml.ui.logout.LogoutRequestSender

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.