/** * Copyright (c) Members of the EGEE Collaboration. 2006-2009. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * 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.glite.authz.pap.services; import java.util.Iterator; import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.glite.authz.pap.common.PAPConfiguration; import org.glite.authz.pap.common.Pap; import org.glite.authz.pap.common.xacml.utils.PolicySetHelper; import org.glite.authz.pap.papmanagement.PapManager; import org.glite.authz.pap.repository.RepositoryManager; import org.glite.authz.pap.services.provisioning.exceptions.MissingIssuerException; import org.glite.authz.pap.services.provisioning.exceptions.VersionMismatchException; import org.glite.authz.pap.services.provisioning.exceptions.WrongFormatIssuerException; import org.joda.time.DateTime; import org.opensaml.Configuration; import org.opensaml.common.SAMLVersion; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.Issuer; import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.core.Statement; import org.opensaml.saml2.core.Status; import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.core.StatusMessage; import org.opensaml.saml2.core.impl.AssertionBuilder; import org.opensaml.saml2.core.impl.IssuerBuilder; import org.opensaml.saml2.core.impl.ResponseBuilder; import org.opensaml.saml2.core.impl.StatusBuilder; import org.opensaml.saml2.core.impl.StatusCodeBuilder; import org.opensaml.saml2.core.impl.StatusMessageBuilder; import org.opensaml.xacml.XACMLObject; import org.opensaml.xacml.policy.PolicySetType; import org.opensaml.xacml.policy.PolicyType; import org.opensaml.xacml.profile.saml.XACMLPolicyQueryType; import org.opensaml.xacml.profile.saml.XACMLPolicyStatementType; import org.opensaml.xacml.profile.saml.impl.XACMLPolicyStatementTypeImplBuilder; import org.opensaml.xml.XMLObjectBuilderFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Valerio Venturi <valerio.venturi@cnaf.infn.it> * */ public class ServicesUtils { @SuppressWarnings("unused") private static Logger logger = LoggerFactory.getLogger(ServicesUtils.class); public static final Object highLevelOperationLock = new Object(); public static void checkQuery(XACMLPolicyQueryType query) throws VersionMismatchException, MissingIssuerException, WrongFormatIssuerException { /* check the version attribute is for a SAML V2.0 query */ if (query.getVersion() != SAMLVersion.VERSION_20) { throw new VersionMismatchException(); } /* TODO check issue instant */ /* check the issuer is present and has the expected format */ Issuer issuer = query.getIssuer(); if (issuer == null) { throw new MissingIssuerException(); } String issuerFormat = issuer.getFormat(); if (issuerFormat != null && !issuerFormat.equals(NameID.ENTITY)) throw new WrongFormatIssuerException(issuerFormat); // TODO Check that the issuer is the same as in the transport } public static Response createErrorResponse(XACMLPolicyQueryType inResponseTo, Exception e) { // get a builder factory XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); /* prepare the response */ ResponseBuilder responseBuilder = (ResponseBuilder) builderFactory.getBuilder(Response.DEFAULT_ELEMENT_NAME); Response response = responseBuilder.buildObject(); // set a few attributes for the response response.setID("_" + UUID.randomUUID().toString()); response.setVersion(SAMLVersion.VERSION_20); response.setIssueInstant(new DateTime()); response.setInResponseTo(inResponseTo.getID()); /* add the Status element */ // build a status object StatusBuilder statusBuilder = (StatusBuilder) builderFactory.getBuilder(Status.DEFAULT_ELEMENT_NAME); Status status = statusBuilder.buildObject(); // build a status code object StatusCodeBuilder statusCodeBuilder = (StatusCodeBuilder) builderFactory.getBuilder(StatusCode.DEFAULT_ELEMENT_NAME); StatusCode statusCode = statusCodeBuilder.buildObject(); // TODO now discriminates by exception but the code must be improved if (e instanceof VersionMismatchException) { statusCode.setValue(StatusCode.VERSION_MISMATCH_URI); } else if (e instanceof MissingIssuerException || e instanceof WrongFormatIssuerException) { // set the status code statusCode.setValue(StatusCode.REQUESTER_URI); // set status message with some details, when provided if (e.getMessage() != null) { StatusMessageBuilder statusMessageBuilder = (StatusMessageBuilder) builderFactory.getBuilder(StatusMessage.DEFAULT_ELEMENT_NAME); StatusMessage statusMessage = statusMessageBuilder.buildObject(); statusMessage.setMessage(e.getMessage()); // add StatusMessage to Status status.setStatusMessage(statusMessage); } } else { /* set status code */ statusCode.setValue(StatusCode.RESPONDER_URI); } // add StatusCode to Status status.setStatusCode(statusCode); response.setStatus(status); return response; } // TODO this method is too long, should be split public static Response createResponse(XACMLPolicyQueryType inResponseTo, List<XACMLObject> policyObjects, HttpServletRequest request) { // get a builder factory XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); /* prepare the Response object to return */ // build a response object ResponseBuilder responseBuilder = (ResponseBuilder) builderFactory.getBuilder(Response.DEFAULT_ELEMENT_NAME); Response response = responseBuilder.buildObject(); // set a few attributes for the response response.setID("_" + UUID.randomUUID().toString()); response.setVersion(SAMLVersion.VERSION_20); response.setIssueInstant(new DateTime()); response.setInResponseTo(inResponseTo.getID()); /* add the Assertion element */ // build an assertion object AssertionBuilder assertionBuilder = (AssertionBuilder) builderFactory.getBuilder(Assertion.DEFAULT_ELEMENT_NAME); Assertion assertion = assertionBuilder.buildObject(); // set a few attributes for the assertion assertion.setID("_" + UUID.randomUUID().toString()); assertion.setVersion(SAMLVersion.VERSION_20); assertion.setIssueInstant(new DateTime()); // build an issuer object IssuerBuilder issuerBuilder = (IssuerBuilder) builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME); Issuer issuer = issuerBuilder.buildObject(); String defaultEntityId = String.format("%s://%s:%s/%s/services/ProvisioningService", request.getScheme(), request.getServerName(), request.getServerPort(), PAPConfiguration.DEFAULT_WEBAPP_CONTEXT); PAPConfiguration conf = PAPConfiguration.instance(); String issuerValue = conf.getString(PAPConfiguration.STANDALONE_SERVICE_STANZA+".entity_id", defaultEntityId); issuer.setValue(issuerValue); assertion.setIssuer(issuer); /* build policy statements objects */ XACMLPolicyStatementTypeImplBuilder policyStatementBuilder = (XACMLPolicyStatementTypeImplBuilder) builderFactory.getBuilder(XACMLPolicyStatementType.TYPE_NAME_XACML20); XACMLPolicyStatementType policyStatement = policyStatementBuilder.buildObject(Statement.DEFAULT_ELEMENT_NAME, XACMLPolicyStatementType.TYPE_NAME_XACML20); Iterator<XACMLObject> iterator = policyObjects.iterator(); while (iterator.hasNext()) { XACMLObject xacmlObject = iterator.next(); if (xacmlObject instanceof PolicySetType) { policyStatement.getPolicySets().add((PolicySetType) xacmlObject); // if (xacmlObject instanceof PolicySetTypeString) { // ((PolicySetTypeString) xacmlObject).releasePolicySetType(); // } } else { policyStatement.getPolicies().add((PolicyType) xacmlObject); // if (xacmlObject instanceof PolicyTypeString) { // ((PolicyTypeString) xacmlObject).releasePolicyType(); // } } // add the statement to the assertion assertion.getStatements().add(policyStatement); } // add the assertion to the response response.getAssertions().add(assertion); /* add the Status element */ // build a status object StatusBuilder statusBuilder = (StatusBuilder) builderFactory.getBuilder(Status.DEFAULT_ELEMENT_NAME); Status status = statusBuilder.buildObject(); // build a status code object StatusCodeBuilder statusCodeBuilder = (StatusCodeBuilder) builderFactory.getBuilder(StatusCode.DEFAULT_ELEMENT_NAME); StatusCode statusCode = statusCodeBuilder.buildObject(); statusCode.setValue(StatusCode.SUCCESS_URI); status.setStatusCode(statusCode); response.setStatus(status); return response; } public static PolicySetType makeRootPolicySet() { String rootPolicySetId = "root-" + PapManager.getInstance().getPap(Pap.DEFAULT_PAP_ALIAS).getId(); PolicySetType rootPolicySet = PolicySetHelper.buildWithAnyTarget(rootPolicySetId, PolicySetHelper.COMB_ALG_FIRST_APPLICABLE); rootPolicySet.setVersion(RepositoryManager.REPOSITORY_MANAGER_VERSION); return rootPolicySet; } }