Package org.apache.cxf.ws.security.wss4j

Source Code of org.apache.cxf.ws.security.wss4j.WSS4JStaxOutInterceptor$WSS4JStaxOutInterceptorInternal

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.apache.cxf.ws.security.wss4j;

import java.io.OutputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
import org.apache.cxf.interceptor.AttachmentOutInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.StaxOutInterceptor;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.ws.policy.AssertionInfoMap;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.wss4j.common.ConfigurationConstants;
import org.apache.wss4j.common.WSSPolicyException;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.stax.ConfigurationConverter;
import org.apache.wss4j.stax.WSSec;
import org.apache.wss4j.stax.ext.OutboundWSSec;
import org.apache.wss4j.stax.ext.WSSSecurityProperties;
import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.impl.OutboundSecurityContextImpl;
import org.apache.xml.security.stax.securityEvent.SecurityEvent;
import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
import org.apache.xml.security.stax.securityToken.OutboundSecurityToken;
import org.apache.xml.security.stax.securityToken.SecurityTokenProvider;

public class WSS4JStaxOutInterceptor extends AbstractWSS4JStaxInterceptor {
   
    public static final String OUTPUT_STREAM_HOLDER =
        WSS4JStaxOutInterceptor.class.getName() + ".outputstream";
    private WSS4JStaxOutInterceptorInternal ending;
   
    private boolean mtomEnabled;
   
    public WSS4JStaxOutInterceptor(WSSSecurityProperties securityProperties) {
        super(securityProperties);
        setPhase(Phase.PRE_STREAM);
        getBefore().add(StaxOutInterceptor.class.getName());
       
        ending = createEndingInterceptor();
    }

    public WSS4JStaxOutInterceptor(Map<String, Object> props) {
        super(props);
        setPhase(Phase.PRE_STREAM);
        getBefore().add(StaxOutInterceptor.class.getName());
       
        ending = createEndingInterceptor();
    }
   
    public WSS4JStaxOutInterceptor() {
        super();
        setPhase(Phase.PRE_STREAM);
        getBefore().add(StaxOutInterceptor.class.getName());
       
        ending = createEndingInterceptor();
    }
   
    public boolean isAllowMTOM() {
        return mtomEnabled;
    }
   
    /**
     * Enable or disable mtom with WS-Security.   By default MTOM is disabled as
     * attachments would not get encrypted or be part of the signature.
     * @param mtomEnabled
     */
    public void setAllowMTOM(boolean allowMTOM) {
        this.mtomEnabled = allowMTOM;
    }
   

    @Override
    public Object getProperty(Object msgContext, String key) {
        return super.getProperty(msgContext, key);
    }

    public void handleMessage(SoapMessage mc) throws Fault {
        //must turn off mtom when using WS-Sec so binary is inlined so it can
        //be properly signed/encrypted/etc...
        if (!mtomEnabled) {
            mc.put(org.apache.cxf.message.Message.MTOM_ENABLED, false);
        }
       
        OutputStream os = mc.getContent(OutputStream.class);
        String encoding = getEncoding(mc);

        XMLStreamWriter newXMLStreamWriter;
        try {
            @SuppressWarnings("unchecked")
            final List<SecurityEvent> requestSecurityEvents =
                (List<SecurityEvent>) mc.getExchange().get(SecurityEvent.class.getName() + ".in");
           
            WSSSecurityProperties secProps = createSecurityProperties();
            translateProperties(mc, secProps);
            Map<String, SecurityTokenProvider<OutboundSecurityToken>> outboundTokens =
                new HashMap<String, SecurityTokenProvider<OutboundSecurityToken>>();
            configureCallbackHandler(mc, secProps);
            configureProperties(mc, outboundTokens, secProps);
           
            OutboundWSSec outboundWSSec = null;
           
            if ((secProps.getActions() == null || secProps.getActions().size() == 0)
                && mc.get(AssertionInfoMap.class) != null) {
                // If no actions configured (with SecurityPolicy) then return
                return;
            }
           
            if (secProps.getAttachmentCallbackHandler() == null) {
                secProps.setAttachmentCallbackHandler(new AttachmentCallbackHandler(mc));
            }
           
            SecurityEventListener securityEventListener =
                configureSecurityEventListener(mc, secProps);
           
            outboundWSSec = WSSec.getOutboundWSSec(secProps);
           
            final OutboundSecurityContextImpl outboundSecurityContext = new OutboundSecurityContextImpl();
            outboundSecurityContext.putList(SecurityEvent.class, requestSecurityEvents);
            outboundSecurityContext.addSecurityEventListener(securityEventListener);
           
            // Save Tokens on the security context
            for (String key : outboundTokens.keySet()) {
                SecurityTokenProvider<OutboundSecurityToken> provider = outboundTokens.get(key);
                outboundSecurityContext.registerSecurityTokenProvider(provider.getId(), provider);
                outboundSecurityContext.put(key, provider.getId());
            }
           
            newXMLStreamWriter = outboundWSSec.processOutMessage(os, encoding, outboundSecurityContext);
            mc.setContent(XMLStreamWriter.class, newXMLStreamWriter);
        } catch (WSSecurityException e) {
            throw new Fault(e);
        } catch (WSSPolicyException e) {
            throw new Fault(e);
        }

        mc.put(AbstractOutDatabindingInterceptor.DISABLE_OUTPUTSTREAM_OPTIMIZATION, Boolean.TRUE);
        mc.put(StaxOutInterceptor.FORCE_START_DOCUMENT, Boolean.TRUE);

        if (MessageUtils.getContextualBoolean(mc, StaxOutInterceptor.FORCE_START_DOCUMENT, false)) {
            try {
                newXMLStreamWriter.writeStartDocument(encoding, "1.0");
            } catch (XMLStreamException e) {
                throw new Fault(e);
            }
            mc.removeContent(OutputStream.class);
            mc.put(OUTPUT_STREAM_HOLDER, os);
        }

        // Add a final interceptor to write end elements
        mc.getInterceptorChain().add(ending);
       
    }
   
    protected SecurityEventListener configureSecurityEventListener(
        final SoapMessage msg, WSSSecurityProperties securityProperties
    ) throws WSSPolicyException {
        final List<SecurityEvent> outgoingSecurityEventList = new LinkedList<SecurityEvent>();
        SecurityEventListener securityEventListener = new SecurityEventListener() {
            @Override
            public void registerSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {
                if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.SamlToken
                    && securityEvent instanceof TokenSecurityEvent) {
                    // Store SAML keys in case we need them on the inbound side
                    TokenSecurityEvent<?> tokenSecurityEvent = (TokenSecurityEvent<?>)securityEvent;
                    WSS4JUtils.parseAndStoreStreamingSecurityToken(tokenSecurityEvent.getSecurityToken(), msg);
                } else {
                    outgoingSecurityEventList.add(securityEvent);
                }
            }
        };
        msg.getExchange().put(SecurityEvent.class.getName() + ".out", outgoingSecurityEventList);
        msg.put(SecurityEvent.class.getName() + ".out", outgoingSecurityEventList);

        return securityEventListener;
    }
   
    protected void configureProperties(
        SoapMessage msg, Map<String, SecurityTokenProvider<OutboundSecurityToken>> outboundTokens,
        WSSSecurityProperties securityProperties
    ) throws WSSecurityException {
        Map<String, Object> config = getProperties();
       
        // Crypto loading only applies for Map
        if (config != null) {
            String user = (String)msg.getContextualProperty(SecurityConstants.USERNAME);
            if (user != null) {
                securityProperties.setTokenUser(user);
            }
            String sigUser = (String)msg.getContextualProperty(SecurityConstants.SIGNATURE_USERNAME);
            if (sigUser != null) {
                securityProperties.setSignatureUser(sigUser);
            }
            String encUser = (String)msg.getContextualProperty(SecurityConstants.ENCRYPT_USERNAME);
            if (encUser != null) {
                securityProperties.setEncryptionUser(encUser);
            }
           
            Crypto sigCrypto =
                loadCrypto(
                    msg,
                    ConfigurationConstants.SIG_PROP_FILE,
                    ConfigurationConstants.SIG_PROP_REF_ID,
                    securityProperties
                );
            if (sigCrypto != null) {
                config.put(ConfigurationConstants.SIG_PROP_REF_ID, "RefId-" + sigCrypto.hashCode());
                config.put("RefId-" + sigCrypto.hashCode(), sigCrypto);
                if (sigUser == null && sigCrypto.getDefaultX509Identifier() != null) {
                    // Fall back to default identifier
                    securityProperties.setSignatureUser(sigCrypto.getDefaultX509Identifier());
                }
            }
           
            Crypto encCrypto =
                loadCrypto(
                    msg,
                    ConfigurationConstants.ENC_PROP_FILE,
                    ConfigurationConstants.ENC_PROP_REF_ID,
                    securityProperties
                );
            if (encCrypto != null) {
                config.put(ConfigurationConstants.ENC_PROP_REF_ID, "RefId-" + encCrypto.hashCode());
                config.put("RefId-" + encCrypto.hashCode(), encCrypto);
                if (encUser == null && encCrypto.getDefaultX509Identifier() != null) {
                    // Fall back to default identifier
                    securityProperties.setEncryptionUser(encCrypto.getDefaultX509Identifier());
                }
            }
            ConfigurationConverter.parseCrypto(config, securityProperties);
           
            if (securityProperties.getSignatureUser() == null && user != null) {
                securityProperties.setSignatureUser(user);
            }
            if (securityProperties.getEncryptionUser() == null && user != null) {
                securityProperties.setEncryptionUser(user);
            }
        }
    }
   
    public final WSS4JStaxOutInterceptorInternal createEndingInterceptor() {
        return new WSS4JStaxOutInterceptorInternal();
    }
   
    private String getEncoding(Message message) {
        Exchange ex = message.getExchange();
        String encoding = (String) message.get(Message.ENCODING);
        if (encoding == null && ex.getInMessage() != null) {
            encoding = (String) ex.getInMessage().get(Message.ENCODING);
            message.put(Message.ENCODING, encoding);
        }

        if (encoding == null) {
            encoding = "UTF-8";
            message.put(Message.ENCODING, encoding);
        }
        return encoding;
    }
   
    final class WSS4JStaxOutInterceptorInternal extends AbstractPhaseInterceptor<Message> {
        public WSS4JStaxOutInterceptorInternal() {
            super(Phase.PRE_STREAM_ENDING);
            getBefore().add(AttachmentOutInterceptor.AttachmentOutEndingInterceptor.class.getName());
        }
       
        public void handleMessage(Message mc) throws Fault {
            try {
                XMLStreamWriter xtw = mc.getContent(XMLStreamWriter.class);
                if (xtw != null) {
                    xtw.writeEndDocument();
                    xtw.flush();
                    xtw.close();
                }

                OutputStream os = (OutputStream) mc.get(OUTPUT_STREAM_HOLDER);
                if (os != null) {
                    mc.setContent(OutputStream.class, os);
                }
                mc.removeContent(XMLStreamWriter.class);
            } catch (XMLStreamException e) {
                throw new Fault(e);
            }
        }

    }
}
TOP

Related Classes of org.apache.cxf.ws.security.wss4j.WSS4JStaxOutInterceptor$WSS4JStaxOutInterceptorInternal

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.