QueryClient.java revision 7865e731ddb5646082d96b96b1a11d82e9db794f
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: QueryClient.java,v 1.9 2009/10/29 00:19:21 madan_ranganath Exp $
*
* Portions Copyrighted 2015-2016 ForgeRock AS.
* Portions Copyrighted 2016 Nomura Research Institute, Ltd.
*/
/**
* The <code>QueryClient</code> class provides Query Requester clients with
* a method to send requests using SOAP connection to SOAP endpoint.
*
*/
public class QueryClient {
static {
try {
new SAML2MetaManager();
} catch (SAML2MetaException sme) {
}
}
private QueryClient() {}
/**
* Returns SAMLv2 <code>Response</code>.
* SAMLv2 request is sent enclosed in the body of a SOAP Message
* to a SOAP endpoint.
* Prior to sending the request query, attributes required for completeness
* of the SAMLv2 Request will be set (eg. Issuer) if not already set.
* Message will be signed if signing is enabled.
* SAMLv2 Query Request will be enclosed in the SOAP Body to create a SOAP
* message to send to the server.
*
* @param request the SAMLv2 <code>RequestAbstract</code> object.
* @param pepEntityID entity identifier of the hosted query requester.
* @param pdpEntityID entity identifier of the remote server.
* @return SAMLv2 <code>Response</code> received from the
* Query Responder.
* @throws SAML2Exception if there is an error processing the query.
*/
throws SAML2Exception {
// retreive pepEntityID metadata
throw new SAML2Exception(
}
// retreive pdpEntityID metadata
throw new SAML2Exception(
}
// set properties in the request.
if (xacmlQuery != null) {
// set Issuer
//generate ID
"wantXACMLAuthzDecisionQuerySigned");
if (wantQuerySigned != null &&
}
}
if (debug.messageEnabled()) {
+ xmlString);
}
// retrieve endpoint from meta data
if (debug.messageEnabled()) {
endPoint);
}
// create SOAP message
try {
endPoint =
if (debug.messageEnabled()) {
}
}
// check the SOAP message for any SOAP related errors
// before passing control to SAML processor
if (debug.messageEnabled()) {
}
}
if (!isTrusted) {
if (debug.messageEnabled()) {
"Issuer in Request is not valid.");
}
args);
throw new SAML2Exception("invalidIssuerInRequest");
}
if (samlResponse != null) {
if (debug.messageEnabled()) {
+ xmlString);
}
response =
if (debug.messageEnabled()) {
"Response with decrypted Assertion: "
+ response.toXMLString(true,true));
}
}
} catch (SOAPException soae) {
if (debug.messageEnabled()) {
}
} catch (Exception e) {
if (debug.messageEnabled()) {
}
throw new SAML2Exception(e.getMessage());
}
}
}
return response;
}
/**
* Returns <code>Issuer</code> for the entity identifier.
*
* @param entityID entity identifier.
* @return the <code>Issuer</code> object.
* @exception <code>SAML2Exception</code> if there is an error creating
* the issuer.
*/
throws SAML2Exception {
return issuer;
}
/**
* Returns SAMLv2 <code>Response</code> object. The <code>Response</code>
* object is created from the String representation of the object.
*
* @param xmlString the String representation of the object.
* @return the <code>Response</code> object.
* @exception <code>IOException</code> if there is an error processing the
* response.
* @exception <code>SAML2Exception</code> if there is an error processing
* the response.
*/
throws IOException,SAML2Exception {
throw new SAML2Exception(
}
if (debug.messageEnabled()) {
}
throw new SAML2Exception(
}
//examine the child element of <SOAP-ENV:Envelope>
if (nodeCount <= 0) {
throw new SAML2Exception(
}
for (int i = 0; i < nodeCount; i++) {
"Child element is missing tag name");
throw new SAML2Exception(
}
for (int j = 0; j < cnodeCount; j++) {
"of child element of <SOAP-ENV:Body>");
throw new SAML2Exception(
"missingChildTagName"));
}
throw new SAML2Exception(
break;
} else {
"element in SOAPBody");
throw new SAML2Exception(
"invalidSOAPBody"));
}
}
} // end of for(int j=0; j <cnodeCount; j++)
}
} else {
throw new SAML2Exception(
}
} // end of if (currentNode.getNodeType() == Node.ELEMENT_NODE)
} // end of for (int i = 0; i < nodeCount; i++)
return samlResponse;
}
/**
* Returns true if the PEP and PDP entities are in the same Circle of
* Trust. Verifies <code>Issuer</code> in <code>Response</code> to
* retreive the PDP entity identity.
*
* @param realm realm of the entity.
* @param pepEntityID PEP entity identifier
* @param pdpEntityID <code>Response</code> issuer identifier.
* @return true if issuer is valid.
* @throws SAML2Exception if there is an error during verification.
*/
boolean isTrusted = false;
try {
} catch (SAML2MetaException sme) {
}
return isTrusted;
}
/**
* Returns the Policy Decision Point End Point (PDP) URL.
*
* @param pdpEntityID entity Identifier of the PDP.
* @return the PDP endpoint URL.
* @exception if there is an error retreiving the endpoint from the
* configuration.
*/
throws SAML2Exception {
if (saml2MetaManager != null) {
try {
if (pdpDescriptor != null) {
while (i.hasNext()) {
if (o instanceof XACMLAuthzServiceElement) {
if (debug.messageEnabled()) {
"EndPoint :" + endPoint);
}
}
break;
}
}
}
} catch (SAML2MetaException sme) {
if (debug.messageEnabled()) {
}
"pdpMetaRetreivalError",args);
}
}
return endPoint;
}
/**
* Returns the extended Policy Enforcement Point Configuration.
*
* @param realm the realm of the entity.
* @param pepEntityId identifier of the PEP.
* @return the <code>XACMLAuthzDecisionQueryConfigElement</code> object.
* @exception <code>SAML2Exception</code> if there is an error retreiving
* the extended configuration.
*/
private static XACMLAuthzDecisionQueryConfigElement getPEPConfig(
if (saml2MetaManager != null) {
try {
} catch (SAML2MetaException sme) {
if (debug.messageEnabled()) {
}
"pepMetaRetreivalError",args);
}
}
return pepConfig;
}
/**
* Returns the extended Policy Decision Point Configuration.
*
* @param realm the realm of the entity.
* @param pdpEntityId identifier of the PDP.
* @return the <code>XACMLPDPConfigElement</code> object.
* @exception <code>SAML2Exception</code> if there is an error retreiving
* the extended configuration.
*/
private static XACMLPDPConfigElement getPDPConfig(
if (saml2MetaManager != null) {
try {
} catch (SAML2MetaException sme) {
if (debug.messageEnabled()) {
}
"pdpMetaRetreivalError",args);
}
}
return pdpConfig;
}
/**
* Returns SAMLv2 <code>Response</code> after validation of the
* response. A new <code>Response</code> object is created which
* contains decrypted assertion if the assertions were encrypted.
*
* @param realm the realm of the entity.
* @param pepEntityID entity identifier of the PEP.
* @param samlResponse the <code>Response</code>.
* @exception <code>SAML2Exception</code> if there is an error.
*/
if (samlResponse != null) {
//validate issuer trust.
}
boolean isTrusted =
if (!isTrusted) {
if (debug.messageEnabled()) {
"Issuer in Response is not valid.");
}
args);
throw new SAML2Exception(
}
// verify signed response
try {
// check if assertion needs to be encrypted,signed.
? true:false;
boolean wantAssertionSigned =
data);
throw new SAML2Exception(
"assertionNotEncrypted"));
}
if (encAssertions != null) {
if (assertions == null) {
assertions = new ArrayList<>();
}
}
}
if (debug.messageEnabled()) {
"no assertion in the Response.");
}
throw new SAML2Exception(
}
// validate Issuer in Assertion
if (wantAssertionSigned) {
pdpDesc =
}
while (assertionIter.hasNext()) {
if (!isTrusted) {
"Assertion's source site is not valid.");
"invalidIssuerInAssertion"));
}
if (debug.messageEnabled()) {
+ "doesn't match the Issuer in Response."
+ respIssuer);
}
throw new SAML2Exception(
}
if (wantAssertionSigned) {
if (debug.messageEnabled()) {
}
"Assertion is not signed or signature " +
"is not valid.");
data);
throw new SAML2Exception(
"invalidSignatureOnAssertion"));
}
}
} //end while
if (wantAssertionEncrypted) {
}
if (debug.messageEnabled()) {
response.toXMLString(true, true));
}
} catch (SAML2MetaException sme) {
if (debug.messageEnabled()) {
}
throw new SAML2Exception(
}
}
return response;
}
/**
* Returns SAMLv2 <code>Response</code> object.
* A new <code>Response</code> object is created from
* the received response to include decrypted assertion
* if the response contained encrypted assertion.
*
* @param samlResponse the <code>Response</code> object.
* @return <code>Response</code> object.
* @exception <code>SAML2Exception</code> if there is an error creating
* the response.
*/
return response;
}
/**
* Returns value of an attribute in the PEP extended configuration.
*
* @param pepConfig the PEP extended configuration object.
* @param attrName the attribute name whose value is to be retreived.
* @return value of the attribute.
* @exception <code>SAML2MetaException</code> if there is an error
* retreiving the value.
*/
private static String getAttributeValueFromPEPConfig(
throws SAML2MetaException {
if (debug.messageEnabled()) {
}
}
}
if (debug.messageEnabled()) {
}
return result;
}
/**
* Returns value of an attribute in the PDP extended configuration.
*
* @param pdpConfig the PDP extended configuration object.
* @param attrName the attribute name whose value is to be retreived.
* @return value of the attribute.
* @exception <code>SAML2MetaException</code> if there is an error
* retreiving the value.
*/
private static String getAttributeValueFromPDPConfig(
throws SAML2MetaException {
if (debug.messageEnabled()) {
}
}
}
if (debug.messageEnabled()) {
}
return result;
}
/**
* Returns true if the assertion is to be signed.
* The PEP Standard metdata configuration is retreived to
* get the value of the attribute WantAssertionsSigned.
*
* @param realm the entity's realm.
* @param pepEntityID entity identifier of the PEP.
* @return true if the value of the attribute is true.
* @exception <code>SAML2MetaException</code> if there is an error
* retreiving the configuration.
*/
throws SAML2MetaException {
return pepDescriptor.isWantAssertionsSigned();
}
/**
*
* @param xacmlQuery XACML Query
* @param realm the entity's realm.
* @param pepEntityID entity identifier of PEP.
* @param pdpEntityID entity identifier of PDP.
* @throws <code>SAML2Exception</code> if error in verifying
* the signature.
*/
"signingCertAlias");
if (signingKey == null) {
throw new SAML2Exception(
}
if (includeCert) {
}
if (signingKey != null) {
}
}
/**
* Verify the signature in <code>Response</code>.
*
* @param pepEntityID entity identifier of PEP.
* @param pdpEntityID entity identifier of PDP.
* @param response <code>Response</code> to be verified
* @return true if signature is valid.
* @throws <code>SAML2Exception</code> if error in verifying
* the signature.
*/
"wantXACMLAuthzDecisionResponseSigned");
boolean valid;
if (wantResponseSigned != null &&
if (!signingCerts.isEmpty()) {
if (debug.messageEnabled()) {
}
} else {
"Incorrect configuration for Signing Certificate.");
throw new SAML2Exception(
}
} else {
if (debug.messageEnabled()) {
"Response doesn't need to be verified.");
}
valid = true;
}
return valid;
}
}