001/*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: XACMLRequestProcessor.java,v 1.4 2009/09/22 23:00:34 madan_ranganath Exp $
026 *
027 * Portions Copyrighted 2016 ForgeRock AS.
028 */
029
030package com.sun.identity.xacml.client;
031
032import static org.forgerock.openam.utils.Time.*;
033
034import java.util.Date;
035import java.util.List;
036
037import com.sun.identity.saml2.assertion.AssertionFactory;
038import com.sun.identity.saml2.assertion.Assertion;
039import com.sun.identity.saml2.assertion.Issuer;
040import com.sun.identity.saml2.common.SAML2Constants;
041import com.sun.identity.saml2.common.SAML2Exception;
042import com.sun.identity.saml2.common.SAML2Utils;
043import com.sun.identity.saml2.soapbinding.QueryClient;
044
045import com.sun.identity.xacml.common.XACMLException;
046
047import com.sun.identity.xacml.common.XACMLException;
048import com.sun.identity.xacml.common.XACMLSDKUtils;
049import com.sun.identity.xacml.context.ContextFactory;
050import com.sun.identity.xacml.context.Request;
051import com.sun.identity.xacml.context.Response;
052import com.sun.identity.xacml.saml2.XACMLAuthzDecisionQuery;
053import com.sun.identity.xacml.saml2.XACMLAuthzDecisionStatement;
054
055/**
056 * This class provides the public API to process XACML context Request. 
057 * This class accepts XACML context Request to get authorization decision,
058 * posts the request to PDP using SAML2 profile, gets SAML Response back, 
059 * extacts XACML context Response from the XACMLAuthzDecisionStatement 
060 * returned in SAML Response and returns the XACML context Response.
061 * XACML context Response includes the xacml context Result with 
062 * the XACML context authorization Decision
063 *
064 * @supported.all.api
065 *
066 */
067public class XACMLRequestProcessor {
068    
069    private XACMLRequestProcessor() {
070    }
071    
072    /**
073     * Returns an instance of <code>XACMLRequestProcessor</code>
074     * @exception if can not return an instance of 
075     *             <code>XACMLRequestProcessor</code>
076     */
077    public static XACMLRequestProcessor getInstance() throws XACMLException {
078        return new XACMLRequestProcessor();
079    }
080
081    /**
082     * Processes an XACML context Request and returns an XACML context 
083     * Response. 
084     *
085     * @param xacmlRequest XACML context Request. This describes the
086     *        Resource(s), Subject(s), Action, Environment of the request
087     *        and corresponds to XACML context schema element Request.
088     *        One would contruct this Request object using XACML client SDK.
089     *
090     * @param pdpEntityId EntityID of PDP
091     * @param pepEntityId EntityID of PEP
092     * @return XACML context Response. This corresponds to 
093     *               XACML context schema element Response
094     * @exception XACMLException if request could not be processed 
095     */
096    public Response processRequest(Request xacmlRequest, 
097            String pdpEntityId, String pepEntityId) 
098            throws XACMLException, SAML2Exception {
099
100        if (XACMLSDKUtils.debug.messageEnabled()) {
101            XACMLSDKUtils.debug.message(
102                    "XACMLRequestProcessor.processRequest(), entering"
103                    + ":pdpEntityId=" + pdpEntityId
104                    + ":pepEntityId=" + pepEntityId
105                    + ":xacmlRequest=\n" 
106                    + xacmlRequest.toXMLString(true, true));
107        }
108        XACMLAuthzDecisionQuery samlpQuery 
109            = createXACMLAuthzDecisionQuery(xacmlRequest);
110
111        //set InputContextOnly
112        samlpQuery.setInputContextOnly(true);
113
114        //set ReturnContext
115        samlpQuery.setReturnContext(true);
116
117        if (XACMLSDKUtils.debug.messageEnabled()) {
118            XACMLSDKUtils.debug.message(
119                    "XACMLRequestProcessor.processRequest(),"
120                    + "samlpQuery=\n" + samlpQuery.toXMLString(true, true));
121        }
122
123        com.sun.identity.saml2.protocol.Response samlpResponse 
124                = QueryClient.processXACMLQuery(samlpQuery,
125                pepEntityId, pdpEntityId);
126        
127        if (XACMLSDKUtils.debug.messageEnabled()) {
128            XACMLSDKUtils.debug.message(
129                    "XACMLRequestProcessor.processRequest(),"
130                    + ":samlpResponse=\n" 
131                    + samlpResponse.toXMLString(true, true));
132        }
133        
134        Response xacmlResponse = null;
135        List assertions = samlpResponse.getAssertion();
136        if (assertions != null) {
137            Assertion assertion = (Assertion)(assertions.get(0));
138            if (assertion != null) {
139                List statements = assertion.getStatements();
140                if (statements.size() > 0) {
141                    String statementString = (String)(statements.get(0));
142                    if (statementString != null) {
143                        XACMLAuthzDecisionStatement statement =
144                          ContextFactory.getInstance()
145                            .createXACMLAuthzDecisionStatement(statementString);
146                        if (XACMLSDKUtils.debug.messageEnabled()) {
147                            XACMLSDKUtils.debug.message(
148                                      "XACMLRequestProcessor.processRequest(),"
149                                    + ":xacmlAuthzDecisionStatement=\n"
150                                    + statement.toXMLString(true, true));
151                        }
152                        if (statement != null) {
153                            xacmlResponse = statement.getResponse();
154                            if (xacmlResponse != null) {
155                                if (XACMLSDKUtils.debug.messageEnabled()) {
156                                    XACMLSDKUtils.debug.message(
157                                        "XACMLRequestProcessor.processRequest()" +
158                                        ",returning :xacmlResponse=\n" +
159                                        xacmlResponse.toXMLString(true, true));
160                                }
161                                return xacmlResponse;
162                            }
163                        }
164                    }
165                }
166            }
167        }
168        return null;
169    }
170
171    //TODO: clean up and fix
172    private XACMLAuthzDecisionQuery createXACMLAuthzDecisionQuery(
173            Request xacmlRequest) 
174            throws XACMLException, SAML2Exception {
175        XACMLAuthzDecisionQuery query 
176                = ContextFactory.getInstance().createXACMLAuthzDecisionQuery();
177        query.setID("query-1");
178        query.setVersion("2.0");
179        query.setIssueInstant(newDate());
180        query.setDestination("destination-uri");
181        query.setConsent("consent-uri");
182
183        Issuer issuer = AssertionFactory.getInstance().createIssuer();
184        issuer.setValue("issuer-1");
185        issuer.setNameQualifier("name-qualifier");
186        //issuer.setSPProvidedID("sp-provided-id");
187        issuer.setSPNameQualifier("sp-name-qualifier");
188        issuer.setSPNameQualifier("sp-name-qualifier");
189        issuer.setFormat("format");
190        query.setIssuer(issuer);
191
192        query.setRequest(xacmlRequest);
193
194        return query;
195    }
196}