All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opensaml.messaging.handler.impl.URLEvaluatingMessageChannelSecurity Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the University Corporation for Advanced Internet Development,
 * Inc. (UCAID) under one or more contributor license agreements.  See the
 * NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The UCAID 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.opensaml.messaging.handler.impl;

import java.net.MalformedURLException;
import java.util.function.Function;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.opensaml.messaging.context.MessageChannelSecurityContext;
import org.opensaml.messaging.context.MessageContext;
import org.opensaml.messaging.handler.MessageHandlerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.net.URLBuilder;

/**
 * Message handler which populates a {@link MessageChannelSecurityContext} based on evaluating a
 * target URL resolved via a configured strategy function.
 */
public class URLEvaluatingMessageChannelSecurity extends AbstractMessageChannelSecurity {
    
    /** Logger. */
    @Nonnull private Logger log = LoggerFactory.getLogger(URLEvaluatingMessageChannelSecurity.class);

    /** Flag controlling whether traffic on the default TLS port is "secure". */
    private boolean defaultPortInsecure;
    
    /** Function which looks up the URL to evaluate. */
    @NonnullAfterInit private Function urlLookup;
    
    /** The target resolved URL. */
    @Nullable private String url;
    
    /** Target resolved and parsed URL. */
    @Nullable private URLBuilder urlBuilder;
    
    /** Constructor. */
    public URLEvaluatingMessageChannelSecurity() {
        defaultPortInsecure = true;
    }
    
    /**
     * Set whether traffic on the default TLS port is "secure" for the purposes of this action.
     * 
     * 

Defaults to "true"

* *

Ordinarily TLS is considered a "secure" channel, but traffic to a default port meant * for browser access tends to rely on server certificates that are unsuited to secure messaging * use cases. This flag allows software layers to recognize traffic on this port as "insecure" and * needing additional security measures.

* * @param flag flag to set */ public void setDefaultPortInsecure(final boolean flag) { ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this); defaultPortInsecure = flag; } /** * Set the function which looks up the destination URL to evaluate. * * @param function the lookup function */ public void setURLLookup(@Nullable final Function function) { urlLookup = function; } /** {@inheritDoc} */ @Override protected void doInitialize() throws ComponentInitializationException { super.doInitialize(); if (urlLookup == null) { throw new ComponentInitializationException("Destination URL lookup function is required"); } } /** {@inheritDoc} */ @Override protected boolean doPreInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException { if (!super.doPreInvoke(messageContext)) { return false; } url = urlLookup.apply(messageContext); if (url != null) { try { urlBuilder = new URLBuilder(url); return super.doPreInvoke(messageContext); } catch (final MalformedURLException e){ log.warn("Unable to parse resolved target URL: {}", url, e); return false; } } log.warn("No target URL resolved, skipping MessageChannelSecurityContext population"); return false; } /** {@inheritDoc} */ @Override protected void doInvoke(@Nonnull final MessageContext messageContext) { final MessageChannelSecurityContext channelContext = getParentContext().getSubcontext(MessageChannelSecurityContext.class, true); final String scheme = urlBuilder.getScheme(); // Note that below we don't care about port if scheme != https, // so only need to worry about default port for https, not all possible schemes. final Integer port = urlBuilder.getPort() != null ? urlBuilder.getPort() : "https".equalsIgnoreCase(scheme) ? 443 : null; log.debug("Evaluating message channel security for scheme '{}' and port '{}' for URL: {}", scheme, port, url); if ("https".equalsIgnoreCase(scheme) && (!defaultPortInsecure || port != 443)) { channelContext.setConfidentialityActive(true); channelContext.setIntegrityActive(true); } else { channelContext.setConfidentialityActive(false); channelContext.setIntegrityActive(false); } log.debug("Set MessageChannelSecurityContext isIntegrityActive: {}", channelContext.isIntegrityActive()); log.debug("Set MessageChannelSecurityContext isConfidentialityActive: {}", channelContext.isConfidentialityActive()); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy