Package org.picketlink.trust.jbossws

Source Code of org.picketlink.trust.jbossws.PicketLinkDispatch$PLMessageContext

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.picketlink.trust.jbossws;

import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.EndpointReference;
import javax.xml.ws.Response;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.picketlink.identity.federation.core.ErrorCodes;
import org.picketlink.identity.federation.core.saml.v2.common.IDGenerator;
import org.picketlink.identity.federation.core.util.Base64;
import org.picketlink.identity.federation.core.util.SOAPUtil;
import org.picketlink.identity.federation.core.util.StringUtil;

/**
* <p>
* A concrete implementation of {@code Dispatch} that can be used as an alternative to the underlying JAXWS implementation.
* </p>
* <p>
* This is used by setting the module option "overrideDispatch" to true in the {@code JBWSTokenIssuingLoginModule}
* </p>
*
* @author Anil.Saldhana@redhat.com
* @since May 10, 2011
*/
public class PicketLinkDispatch implements Dispatch<Source> {
    @SuppressWarnings("rawtypes")
    private Dispatch parent;
    private String endpoint;

    private boolean useWSSE = false;
    private SSLSocketFactory sslSocketFactory;

    @SuppressWarnings("rawtypes")
    public PicketLinkDispatch(Dispatch parent, String endpoint) {
        this.parent = parent;
        this.endpoint = endpoint;
    }

    public void setUseWSSE(boolean val) {
        this.useWSSE = val;
    }

    public void setSSLSocketFactory(SSLSocketFactory ssl) {
        this.sslSocketFactory = ssl;
    }

    public Map<String, Object> getRequestContext() {
        return parent.getRequestContext();
    }

    public Map<String, Object> getResponseContext() {
        return parent.getResponseContext();
    }

    public Binding getBinding() {
        return parent.getBinding();
    }

    public EndpointReference getEndpointReference() {
        return parent.getEndpointReference();
    }

    public <T extends EndpointReference> T getEndpointReference(Class<T> clazz) {
        return parent.getEndpointReference(clazz);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Source invoke(Source requestMessage) {
        PLMessageContext msgContext = new PLMessageContext();
        msgContext.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, Boolean.TRUE);

        /** The JACC PolicyContext key for the current Subject */
        String WEB_REQUEST_KEY = "javax.servlet.http.HttpServletRequest";

        HttpServletRequest request = null;
        try {
            request = (HttpServletRequest) PolicyContext.getContext(WEB_REQUEST_KEY);
        } catch (PolicyContextException e1) {
            throw new RuntimeException(e1);
        }
        msgContext.put(MessageContext.SERVLET_REQUEST, request);

        SOAPMessage soapMessage = null;
        try {
            soapMessage = SOAPUtil.create();
        } catch (SOAPException e2) {
            throw new RuntimeException(e2);
        }
        String userName = (String) parent.getRequestContext().get(BindingProvider.USERNAME_PROPERTY);
        String passwd = (String) parent.getRequestContext().get(BindingProvider.PASSWORD_PROPERTY);
        if (StringUtil.isNotNull(userName)) {
            try {
                if (useWSSE) {
                    SOAPElement security = create(userName, passwd);
                    soapMessage.getSOAPHeader().appendChild(security);
                } else {
                    String authorization = Base64.encodeBytes((userName + ":" + passwd).getBytes());
                    soapMessage.getMimeHeaders().addHeader("Authorization", "Basic " + authorization);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        try {
            SOAPUtil.addData(requestMessage, soapMessage);
        } catch (SOAPException e1) {
            throw new RuntimeException(e1);
        }
        msgContext.setMessage(soapMessage);

        List<Handler> handlers = getBinding().getHandlerChain();
        for (Handler handler : handlers) {
            boolean result = handler.handleMessage(msgContext);
            if (!result)
                throw new WebServiceException(ErrorCodes.PROCESSING_EXCEPTION + "Handler " + handler.getClass()
                        + " returned false");
        }

        if (sslSocketFactory != null) {
            HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
        }

        SOAPMessage response = null;
        try {
            SOAPConnectionFactory connectFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection connection = connectFactory.createConnection();
            // Send it across the wire
            URL url = new URL(endpoint);

            response = connection.call(soapMessage, url);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        try {
            return new DOMSource(SOAPUtil.getSOAPData(response));
        } catch (SOAPException e) {
            throw new RuntimeException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public Response<Source> invokeAsync(Source msg) {
        return parent.invokeAsync(msg);
    }

    @SuppressWarnings("unchecked")
    public Future<?> invokeAsync(Source msg, AsyncHandler<Source> handler) {
        return parent.invokeAsync(msg, handler);
    }

    @SuppressWarnings("unchecked")
    public void invokeOneWay(Source msg) {
        parent.invokeOneWay(msg);
    }

    public static class PLMessageContext implements MessageContext, SOAPMessageContext {
        private Map<String, Object> map = new HashMap<String, Object>();
        private Map<String, Scope> scopeMap = new HashMap<String, MessageContext.Scope>();

        private Map<String, Object> properties = new HashMap<String, Object>();

        private SOAPMessage message;

        public int size() {
            return map.size();
        }

        public boolean isEmpty() {
            return map.isEmpty();
        }

        public boolean containsKey(Object key) {
            return map.containsKey(key);
        }

        public boolean containsValue(Object value) {
            return map.containsValue(value);
        }

        public Object get(Object key) {
            return map.get(key);
        }

        public Object put(String key, Object value) {
            return map.put(key, value);
        }

        public Object remove(Object key) {
            return map.remove(key);
        }

        public void putAll(Map<? extends String, ? extends Object> m) {
            map.putAll(m);
        }

        public void clear() {
            map.clear();
        }

        public Set<String> keySet() {
            return map.keySet();
        }

        public Collection<Object> values() {
            return map.values();
        }

        public Set<java.util.Map.Entry<String, Object>> entrySet() {
            return map.entrySet();
        }

        public void setScope(String name, Scope scope) {
            this.scopeMap.put(name, scope);
        }

        public Scope getScope(String name) {
            return scopeMap.get(name);
        }

        public boolean containsProperty(String name) {
            return properties.containsKey(name);
        }

        public Object getProperty(String name) {
            return properties.get(name);
        }

        @SuppressWarnings("rawtypes")
        public Iterator getPropertyNames() {
            return properties.keySet().iterator();
        }

        public void removeProperty(String name) {
            properties.remove(name);
        }

        public void setProperty(String name, Object value) {
            properties.put(name, value);
        }

        public SOAPMessage getMessage() {
            return message;
        }

        public void setMessage(SOAPMessage message) {
            this.message = message;
        }

        public Object[] getHeaders(QName header, JAXBContext context, boolean allRoles) {
            throw new RuntimeException();
        }

        public Set<String> getRoles() {
            throw new RuntimeException();
        }
    }

    /**
     * Given username and pass, create a {@link SOAPElement} for WSSE UsernameToken Profile
     *
     * @param token
     * @return
     * @throws SOAPException
     */
    private SOAPElement create(String userName, String pass) throws SOAPException {
        SOAPFactory factory = SOAPFactory.newInstance();
        SOAPElement security = factory.createElement(Constants.WSSE_LOCAL, Constants.WSSE_PREFIX, Constants.WSSE_NS);
        security.addNamespaceDeclaration(Constants.WSU_PREFIX, Constants.WSU_NS);

        SOAPElement userNameToken = factory.createElement(Constants.WSSE_USERNAME_TOKEN, Constants.WSSE_PREFIX,
                Constants.WSSE_NS);
        userNameToken.addAttribute(new QName(Constants.WSU_NS, "Id", Constants.WSU_PREFIX), IDGenerator.create("token-"));

        SOAPElement un = factory.createElement(Constants.WSSE_USERNAME, Constants.WSSE_PREFIX, Constants.WSSE_NS);
        un.addTextNode(userName);
        userNameToken.addChildElement(un);

        SOAPElement passElement = factory.createElement(Constants.WSSE_PASSWORD, Constants.WSSE_PREFIX, Constants.WSSE_NS);
        passElement.addAttribute(new QName("Type"), Constants.WSSE_PASSWORD_TEXT_NS);
        passElement.addTextNode(pass);
        userNameToken.addChildElement(passElement);

        security.addChildElement(userNameToken);
        return security;
    }
}
TOP

Related Classes of org.picketlink.trust.jbossws.PicketLinkDispatch$PLMessageContext

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.