Package org.picketlink.trust.jbossws.handler

Source Code of org.picketlink.trust.jbossws.handler.BinaryTokenHandler

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

import java.util.ArrayList;
import java.util.List;

import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.picketlink.identity.federation.core.util.SOAPUtil;
import org.picketlink.identity.federation.core.util.StringUtil;
import org.picketlink.trust.jbossws.Constants;
import org.picketlink.trust.jbossws.Util;

/**
* <p>
* Handler that looks for a binary data that exists in the HTTP payload either as a header or a cookie based on configuration.
* </p>
* <p>
* <b>Configuration:</b>
* <p>
* <i>System Properties:</i>
* <ul>
* <li>binary.http.header: http header name. Can be a comma separated set of names</li>
* <li>binary.http.cookie: http cookie name</li>
* <li>binary.http.encodingType: attribute value of the EncodingType attribute</li>
* <li>binary.http.valueType: attribute value of the ValueType attribute</li>
* <li>binary.http.valueType.namespace: namespace for the ValueType attribute</li>
* <li>binary.http.valueType.prefix: namespace for the ValueType attribute</li>
* <li>binary.http.cleanToken: true or false dependending on whether the binary token has to be cleaned</li>
* </ul>
* <i>Setters:</i>
* <p>
* Please see the see also section.
* </p>
*
* @see #setHttpHeaderName(String)
* @see #setHttpCookieName(String)
* @see #setEncodingType(String)
* @see #setValueType(String)
* @see #setValueTypeNamespace(String)
* @see #setValueTypePrefix(String)
* @see #setCleanToken(boolean) </p> </p>
* @author Anil.Saldhana@redhat.com
* @since Apr 5, 2011
*/
public class BinaryTokenHandler extends AbstractPicketLinkTrustHandler {
    /**
     * The HTTP header name that this token looks for. Either this or the httpCookieName should be set.
     */
    private String httpHeaderName = SecurityActions.getSystemProperty("binary.http.header", null);

    /**
     * The HTTP cookie name that this token looks for. Either this or the httpHeaderName should be set.
     */
    private String httpCookieName = SecurityActions.getSystemProperty("binary.http.cookie", null);

    /**
     * Attribute value for the EncodingType attribute
     */
    private String encodingType = SecurityActions.getSystemProperty("binary.http.encodingType",
            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");

    /**
     * Attribute value for the ValueType attribute
     */
    private String valueType = SecurityActions.getSystemProperty("binary.http.valueType", null);

    /**
     * Namespace for the ValueType. Can be null. If null, then a separate namespace is not added.
     */
    private String valueTypeNamespace = SecurityActions.getSystemProperty("binary.http.valueType.namespace", null);

    /**
     * Prefix for the ValueType. Can be null.
     */
    private String valueTypePrefix = SecurityActions.getSystemProperty("binary.http.valueType.prefix", null);

    /**
     * Some binary tokens need to be cleaned. This handler just cleans upto the first blank space and discards before that.
     */
    private boolean cleanToken = Boolean.parseBoolean(SecurityActions.getSystemProperty("binary.http.cleanToken", "false"));

    private SOAPFactory factory = null;

    /**
     * <p>
     * Set the EncodingType value.
     * </p>
     * <p>
     * Alternatively, set the system property "binary.http.encodingType"
     * </p>
     *
     * @param binaryEncodingType
     */
    public void setEncodingType(String binaryEncodingType) {
        this.encodingType = binaryEncodingType;
    }

    /**
     * <p>
     * Set the Value type
     * </p>
     * <p>
     * Alternatively, set the system property "binary.http.valueType"
     * </p>
     *
     * @param binaryValueType
     */
    public void setValueType(String binaryValueType) {
        this.valueType = binaryValueType;
    }

    /**
     * <p>
     * Set the ValueType Namespace
     * </p>
     * <p>
     * Alternatively, set the system property "binary.http.valueType.namespace"
     * </p>
     *
     * @param binaryValueNamespace
     */
    public void setValueTypeNamespace(String binaryValueNamespace) {
        this.valueTypeNamespace = binaryValueNamespace;
    }

    /**
     * <p>
     * Set the Value Type Prefix
     * </p>
     * <p>
     * Alternatively, set the system property "binary.http.valueType.prefix"
     * </p>
     *
     * @param binaryValuePrefix
     */
    public void setValueTypePrefix(String binaryValuePrefix) {
        this.valueTypePrefix = binaryValuePrefix;
    }

    /**
     * <p>
     * Set the Http Header Name
     * </p>
     * <p>
     * Alternatively, set the system property: "binary.http.header"
     * </p>
     *
     * @param http
     */
    public void setHttpHeaderName(String http) {
        httpHeaderName = http;
    }

    /**
     * <p>
     * Set the Http Cookie Name
     * </p>
     * <p>
     * Alternatively, set the system property: ""binary.http.cookie"
     * </p>
     *
     * @param http
     */
    public void setHttpCookieName(String http) {
        httpCookieName = http;
    }

    /**
     * <p>
     * Should we not clean the extracted binary token.
     * </p>
     * <p>
     * Alternatively, set the system property: "binary.http.cleanToken"
     * </p>
     *
     * @param clean
     */
    public void setCleanToken(boolean clean) {
        this.cleanToken = clean;
    }

    @Override
    protected boolean handleOutbound(MessageContext msgContext) {

        logger.trace("Handling Outbound Message");

        if (httpHeaderName == null && httpCookieName == null)
            throw logger.injectedValueMissing("Either httpHeaderName or httpCookieName should be set");

        HttpServletRequest servletRequest = getHttpRequest(msgContext);
        if (servletRequest == null)
            throw logger.nullValueError("Http request");

        String token = getTokenValue(servletRequest);
        if (token == null)
            throw logger.nullValueError("Null Token");
        SOAPElement security = null;
        try {
            security = create(token);
        } catch (SOAPException e) {
            logger.jbossWSUnableToCreateBinaryToken(e);
        }
        if (security == null) {
            logger.jbossWSUnableToCreateSecurityToken();
            return true;
        }
        SOAPMessage sm = ((SOAPMessageContext) msgContext).getMessage();
        SOAPEnvelope envelope;
        try {
            envelope = sm.getSOAPPart().getEnvelope();
            SOAPHeader header = (SOAPHeader) Util.findElement(envelope, new QName(envelope.getNamespaceURI(), "Header"));
            if (header == null) {
                header = (SOAPHeader) envelope.getOwnerDocument().createElementNS(envelope.getNamespaceURI(),
                        envelope.getPrefix() + ":Header");
                envelope.insertBefore(header, envelope.getFirstChild());
            }
            header.addChildElement(security);
        } catch (SOAPException e) {
            logger.jbossWSUnableToCreateBinaryToken(e);
        }
        if (logger.isTraceEnabled()) {
            logger.trace("SOAP Message=" + SOAPUtil.soapMessageAsString(sm));           
        }
        return true;
    }

    /**
     * Get the {@link HttpServletRequest} from the {@link MessageContext}
     *
     * @param msgContext
     * @return
     */
    private HttpServletRequest getHttpRequest(MessageContext msgContext) {
        HttpServletRequest request = (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST);
        if (request == null) {
            try {
                request = (HttpServletRequest) PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
            } catch (PolicyContextException e) {
                throw new RuntimeException(e);
            }
        }
        return request;
    }

    /**
     * Given the {@link HttpServletRequest}, look for the http header or the cookie depending on the configuration
     *
     * @param http
     * @return
     */
    private String getTokenValue(HttpServletRequest http) {
        if (httpHeaderName != null && !httpHeaderName.isEmpty()) {
            // Sometime the http header name can be a comma separated list of names
            if (httpHeaderName.contains(",")) {
                List<String> headers = getHeaderNames(httpHeaderName);
                StringBuilder builder = new StringBuilder();
                for (String header : headers) {
                    String value = getTokenValue(http, header);
                    if (value != null)
                        builder.append(value);
                }
                String headerValue = builder.toString();

                logger.trace("Header value has been identified " + headerValue);
               
                return clean(headerValue);
            } else {
                String header = http.getHeader(httpHeaderName);
                if (header != null) {
                    logger.trace("Header value has been identified " + header);
                    return clean(header);
                }
            }
        }
        if (httpCookieName != null && !httpCookieName.isEmpty()) {
            Cookie[] cookies = http.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals(httpCookieName)) {
                        logger.trace("Cookie value has been identified " + cookie.getValue());
                        return clean(cookie.getValue());
                    }
                }
            }
        }
        return null;
    }

    private String getTokenValue(HttpServletRequest http, String header) {
        String headerValue = http.getHeader(header);
        if (headerValue != null && !headerValue.isEmpty()) {
            return clean(headerValue);
        }
        return null;
    }

    /**
     * Given a binary token, create a {@link SOAPElement}
     *
     * @param token
     * @return
     * @throws SOAPException
     */
    private SOAPElement create(String token) throws SOAPException {
        if (factory == null)
            factory = SOAPFactory.newInstance();
        SOAPElement security = factory.createElement(Constants.WSSE_LOCAL, Constants.WSSE_PREFIX, Constants.WSSE_NS);

        if (valueTypeNamespace != null) {
            security.addNamespaceDeclaration(valueTypePrefix, valueTypeNamespace);
        }

        SOAPElement binarySecurityToken = factory.createElement(Constants.WSSE_BINARY_SECURITY_TOKEN, Constants.WSSE_PREFIX,
                Constants.WSSE_NS);
        binarySecurityToken.addTextNode(token);
        if (valueType != null && !valueType.isEmpty()) {
            binarySecurityToken.setAttribute(Constants.WSSE_VALUE_TYPE, valueType);
        }
        if (encodingType != null) {
            binarySecurityToken.setAttribute(Constants.WSSE_ENCODING_TYPE, encodingType);
        }

        security.addChildElement(binarySecurityToken);
        return security;
    }

    /**
     * Some 3rd party systems send in the binary token in the format Discardable<space>ValidToken
     *
     * @param value
     * @return
     */
    private String clean(String value) {
        int i = -1;

        if (cleanToken) {
            value = value.trim();
            while ((i = value.indexOf(' ')) != -1) {
                value = value.substring(i + 1);
            }
        }
        return value;
    }

    private List<String> getHeaderNames(String str) {
        List<String> list = new ArrayList<String>();
        if (StringUtil.isNotNull(str)) {
            list.addAll(StringUtil.tokenize(str));
        }
        return list;
    }
}
TOP

Related Classes of org.picketlink.trust.jbossws.handler.BinaryTokenHandler

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.