Package org.fcrepo.server.security.xacml.pep.ws

Source Code of org.fcrepo.server.security.xacml.pep.ws.PEP

/*
* File: PEP.java
*
* Copyright 2007 Macquarie E-Learning Centre Of Excellence
*
* Licensed 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.fcrepo.server.security.xacml.pep.ws;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.fcrepo.server.security.xacml.pep.AuthzDeniedException;
import org.fcrepo.server.security.xacml.pep.ContextHandler;
import org.fcrepo.server.security.xacml.pep.PEPException;
import org.fcrepo.server.security.xacml.pep.ws.operations.OperationHandler;
import org.fcrepo.server.security.xacml.pep.ws.operations.OperationHandlerException;
import org.fcrepo.server.utilities.CXFUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.ctx.Result;

/**
* This class is an JAX-WS handler. It is used as a handler on both the request
* and response. The handler examines the operation for the request and
* retrieves an appropriate handler to manage the request.
*
* @author Jiri Kremser
*/
public class PEP
        implements javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext> {


    private static final Logger logger = LoggerFactory.getLogger(PEP.class);

    /**
     * A list of instantiated handlers. As operations are invoked, handlers for
     * those operations are created and added to this list
     */
    private Map<String, Map<String, OperationHandler>> m_serviceHandlers = null;

    /**
     * The XACML context handler.
     */
    ContextHandler m_ctxHandler = null;

    private final boolean feslAuthZ;

    /**
     * A time stamp to note the time this AuthHandler was instantiated.
     */
    private Date m_ts = null;

    /**
     * Default constructor that initialises the handlers map and the
     * contextHandler.
     *
     * @throws PEPException
     */
    public PEP(boolean feslAuthZ)
            throws PEPException {
        super();
        this.feslAuthZ = feslAuthZ;
        logger.info("feslAuthZ = " + feslAuthZ);
        if (feslAuthZ) {
            m_serviceHandlers = new HashMap<String, Map<String,OperationHandler>>(0);
            m_ts = new Date();
        }
    }

    public void setContextHandler(ContextHandler ctxHandler) {
        m_ctxHandler = ctxHandler;
    }

    public void setServiceHandlers(Map<String, Map<String,OperationHandler>> serviceHandlers) {
        m_serviceHandlers = serviceHandlers;
    }

    /*
     * (non-Javadoc)
     */
    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        if (!feslAuthZ) {
            return true;
        }
        String service =
                ((QName) context.get(SOAPMessageContext.WSDL_SERVICE))
                        .getLocalPart();
        String operation =
                ((QName) context.get(SOAPMessageContext.WSDL_OPERATION))
                        .getLocalPart();
        if (logger.isDebugEnabled()) {
            logger.debug("AuthHandler executed: " + service + "/" + operation
                    + " [" + m_ts + "]");
        }

        //        // Obtain the service details
        //        ServiceDesc service = context.getService().getServiceDescription();
        //        // Obtain the operation details and message type
        //        OperationDesc operation = context.getOperation();
        // Obtain a class to handle our request
        OperationHandler operationHandler = getHandler(service, operation);

        // there must always be a handler.
        if (operationHandler == null) {
            logger.error("Missing handler for service/operation: " + service
                    + "/" + operation);
            throw CXFUtility
                    .getFault(new PEPException("Missing handler for service/operation: "
                            + service + "/" + operation));
        }

        RequestCtx reqCtx = null;

        // if we are on the request pathway, outboundProperty == false. True on
        // response pathway
        Boolean outboundProperty =
                (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        try {
            if (outboundProperty) {
                reqCtx = operationHandler.handleResponse(context);
            } else {
                reqCtx = operationHandler.handleRequest(context);
            }
        } catch (OperationHandlerException ohe) {
            logger.error("Error handling operation: " + operation, ohe);
            throw CXFUtility
                    .getFault(new PEPException("Error handling operation: "
                            + operation, ohe));
        }

        // if handler returns null, then there is no work to do (would have
        // thrown exception if things went wrong).
        if (reqCtx == null) {
            return false;
        }

        // if we have received a requestContext, we need to hand it over to the
        // context handler for resolution.
        ResponseCtx resCtx = null;

        try {
            resCtx = m_ctxHandler.evaluate(reqCtx);
        } catch (PEPException pe) {
            logger.error("Error evaluating request", pe);
            throw CXFUtility
                    .getFault(new PEPException("Error evaluating request (operation: "
                                                       + operation + ")",
                                               pe));
        }

        // TODO: set obligations
        /*
         * Need to set obligations in some sort of map, with UserID/SessionID +
         * list of obligationIDs. Enforce will have to check that these
         * obligations are met before providing access. There will need to be an
         * external obligations service that this PEP can communicate with. Will
         * be working on that... This service will throw an 'Obligations need to
         * be met' exception for outstanding obligations
         */

        // TODO: enforce will need to ensure that obligations are met.
        enforce(resCtx);
        return true;
    }

    /**
     * Function to try and obtain a handler using the name of the current SOAP
     * service and operation.
     *
     * @param opName
     *        the name of the operation
     * @return OperationHandler to handle the operation
     */
    private OperationHandler getHandler(String serviceName, String operationName) {
        if (serviceName == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Service Name was null!");
            }

            return null;
        }

        if (operationName == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Operation Name was null!");
            }

            return null;
        }

        Map<String, OperationHandler> handlers =
                m_serviceHandlers.get(serviceName);
        if (handlers == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("No Service Handlers found for: " + serviceName);
            }

            return null;
        }

        OperationHandler handler = handlers.get(operationName);
        if (handler == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Handler not found for: " + serviceName + "/"
                        + operationName);
            }
        }

        return handler;
    }

    /**
     * Method to check a response and enforce any denial. This is achieved by
     * throwing an SoapFault.
     *
     * @param res
     *        the ResponseCtx
     */
    private void enforce(ResponseCtx res) {
        @SuppressWarnings("unchecked")
        Set<Result> results = res.getResults();
        for (Result r : results) {
            if (r.getDecision() != Result.DECISION_PERMIT) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Denying access: " + r.getDecision());
                }
                switch (r.getDecision()) {
                    case Result.DECISION_DENY:
                        throw CXFUtility
                                .getFault(new AuthzDeniedException("Deny"));

                    case Result.DECISION_INDETERMINATE:
                        throw CXFUtility
                                .getFault(new AuthzDeniedException("Indeterminate"));
                    case Result.DECISION_NOT_APPLICABLE:
                        throw CXFUtility
                                .getFault(new AuthzDeniedException("NotApplicable"));
                    default:
                }
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Permitting access!");
        }
    }

    /**
     * {@inheritDoc}
     */

    @Override
    public void close(MessageContext arg0) {
    }

    /**
     * {@inheritDoc}
     */

    @Override
    public boolean handleFault(SOAPMessageContext arg0) {
        return false;
    }

    /**
     * {@inheritDoc}
     */

    @Override
    public Set<QName> getHeaders() {
        return null;

    }
}
TOP

Related Classes of org.fcrepo.server.security.xacml.pep.ws.PEP

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.