SOAPRequestHandler.java revision 4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1c
/**
* 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: SOAPRequestHandler.java,v 1.47 2010/01/15 18:54:34 mrudul_uchil Exp $
*
*/
/* iPlanet-PUBLIC-CLASS */
/**
* This class <code>SOAPRequestHandler</code> is to process and secure the
* in-bound or out-bound <code>SOAPMessage</code>s of the web service clients
* and web service providers.
*
* <p> This class processes the <code>SOAPMessage</code>s for the
* web services security according to the processing rules defined in
* OASIS web services security specification and as well as the Liberty
* Identity Web services security framework.
*
*/
public class SOAPRequestHandler implements SOAPRequestHandlerInterface {
/**
* Property for web services authenticator.
*/
private static final String WSS_AUTHENTICATOR =
"com.sun.identity.wss.security.authenticator";
private static final String WSS_AUTHORIZER =
"com.sun.identity.wss.security.authorizer";
/**
* Property string for liberty authentication service url.
*/
private static final String LIBERTY_AUTHN_URL =
"com.sun.identity.liberty.authnsvc.url";
/**
* Property for the SAML issuer name.
*/
private static final String ASSERTION_ISSUER =
"com.sun.identity.wss.security.samlassertion.issuer";
/**
* Initializes the handler with the given configuration.
*
* @param config the configuration map to initializate the provider.
*
* @exception SecurityException if the initialization fails.
*/
if(debug.messageEnabled()) {
}
}
/**
* Authenticates the <code>SOAPMessage</code> from a remote client.
*
* @param soapRequest SOAPMessage that needs to be validated.
*
* @param subject the subject that may be used by the callers
* to store Principals and credentials validated in the request.
*
* @param sharedState that may be used to store any shared state
* information between <code>validateRequest and <secureResponse>
*
* @param request the <code>HttpServletRequest</code> associated with
* this SOAP Message request.
*
* @param response the <code>HttpServletResponse</code> associated with
* this SOAP Message response.
*
* @return Object the authenticated token.
*
* @exception SecurityException if any error occured during validation.
*/
throws SecurityException {
if(debug.messageEnabled()) {
"Received SOAP message Before validation: "
}
try {
if(debug.messageEnabled()) {
"SOAPFault code : " + code);
"SOAPFault errorString : " + errorString);
}
throw new SecurityException(
}
} catch (SOAPException se) {
}
sharedState = new HashMap();
}
if (LogUtil.isLogEnabled()) {
data,
null);
}
boolean isSTS =
if (isSTS) {
stsConfig = new STSRemoteConfig();
} else {
config = getWSPConfig();
}
if(isLibertyMessage(soapRequest)) {
if(debug.messageEnabled()) {
"SOAPMessage is of liberty message type.");
}
try {
return subject;
} catch (SOAPBindingException sbe) {
"BindingException:: ", sbe);
}
}
new SecureSOAPMessage(soapRequest, false);
if(remoteProvider != null) {
}
} else {
}
(config.isRequestHeaderEncryptEnabled()))) ) {
}
throw new SecurityException(
}
}
if(debug.messageEnabled()) {
"soap message security mechanism: " + uri);
}
// delay the signature verification after authentication
// for kerberos token.
if (!secureMsg.verifySignature()) {
if(debug.warningEnabled()) {
"Signature verification failed.");
}
throw new SecurityException(
} else {
if(debug.messageEnabled()) {
"Signature verification successful");
}
}
}
}
}
if(debug.messageEnabled()) {
"list of accepted SecurityMechanisms : " + list);
}
if(debug.warningEnabled()) {
+ "unsupported security mechanism");
}
throw new SecurityException(
} else {
if(debug.messageEnabled()) {
"provider is not configured for the incoming message " +
" level type but allows anonymous");
}
return subject;
}
}
return subject;
}
config.getProviderName())) {
throw new SecurityException(
}
}
break;
}
}
+ "verification failed.");
throw new SecurityException(
}
}
if(!isSTS) {
}
if(debug.messageEnabled()) {
" at the end of Validate request **");
}
if (LogUtil.isLogEnabled()) {
null);
}
config, false)) {
if(debug.messageEnabled()) {
" Unauthorized. ");
}
}
return subject;
}
/**
* Secures the SOAP Message response to the client.
*
* @param soapMessage SOAP Message that needs to be secured.
*
* @param sharedState a map for the callers to store any state information
* between <code>validateRequest</code> and
* <code>secureResponse</code>.
*
* @exception SecurityException if any error occurs during securing.
*/
if(debug.messageEnabled()) {
"Input SOAP message before securing : " +
}
try {
if(debug.messageEnabled()) {
"SOAPFault code : " + code);
"SOAPFault errorString : " + errorString);
}
throw new SecurityException(
}
} catch (SOAPException se) {
}
sharedState = new HashMap();
}
if (LogUtil.isLogEnabled()) {
data,
null);
}
boolean isSTS =
if (isSTS) {
stsConfig = new STSRemoteConfig();
} else {
config = getWSPConfig();
}
if(debug.messageEnabled()) {
}
try {
} catch (SOAPBindingException sbe) {
"BindingException.", sbe);
}
}
true, config.getSignedElements());
try {
} catch (SOAPException se) {
}
(!config.isResponseSignEnabled() &&
!config.isResponseEncryptEnabled())) ){
return soapMessage;
}
}
}
} else {
if(clientCertAlias != null) {
}
}
config.getEncryptionStrength(),true,false);
}
if (LogUtil.isLogEnabled()) {
null);
}
if(debug.messageEnabled()) {
"Secured SOAP response : " +
}
return soapMessage;
}
/**
* Secures the <code>SOAPMessage</code> request by adding necessary
* credential information.
*
* @param soapMessage the <code>SOAPMessage</code> that needs to be secured.
*
* @param subject the <code>Subject<code> of the authenticating entity.
*
* @param sharedState Any shared state information that may be used between
* the <code>secureRequest</code> and <code>validateResponse</code>.
*
* @exception SecurityException if any failure for securing the request.
*/
public SOAPMessage secureRequest (
if (LogUtil.isLogEnabled()) {
data,
null);
}
"Provider configuration from shared map is null");
}
config = getWSCConfig();
}
throw new SecurityException(
}
}
}
} else {
if (securityMechanism.isTALookupRequired()) {
if(debug.messageEnabled()) {
+ "using STS for security tokens");
}
if(config.usePassThroughSecurityToken()) {
if(debug.messageEnabled()) {
" using the authenticated subject");
}
}
}
if(debug.messageEnabled()) {
"using thread local for SSOToken");
}
}
"is available. ");
}
throw new SecurityException(
}
if(debug.messageEnabled()) {
+ " using liberty security");
}
} else {
try {
}
if(customToken == null) {
if(debug.messageEnabled()) {
+ " using sso token as OBOToken");
}
ssoToken);
} else {
if(debug.messageEnabled()) {
+ " using custom token as OBOToken");
}
}
if(signingKey != null) {
}
} catch (FAMSTSException stsEx) {
"in obtaining STS Token", stsEx);
}
}
} else {
if(debug.messageEnabled()) {
" Generate security tokens locally");
}
}
}
}
}
if(config.isRequestSignEnabled()) {
}
if((config.isRequestEncryptEnabled()) ||
}
if (LogUtil.isLogEnabled()) {
null);
}
if(debug.messageEnabled()) {
}
return soapMessage;
}
/**
* Validates the SOAP Response from the service provider.
*
* @param soapMessage the <code>SOAPMessage</code> that needs to be
* validated.
*
* @param sharedState Any shared data that may be used between the
* <code>secureRequest</code> and <code>validateResponse</code>.
*
* @exception SecurityException if any failure occured for validating the
* response.
*/
if(debug.messageEnabled()) {
"Input SOAP message : " +
}
try {
if(debug.messageEnabled()) {
"SOAPFault code : " + code);
"SOAPFault errorString : " + errorString);
}
throw new SecurityException(
}
} catch (SOAPException se) {
}
if (LogUtil.isLogEnabled()) {
data,
null);
}
"Provider configuration from shared map is null");
}
config = getWSCConfig();
}
if(isLibertyMessage(soapMessage)) {
try {
return;
} catch (SOAPBindingException sbe) {
"BindingException. ", sbe);
}
}
|| config.isResponseSignEnabled()) {
new SecureSOAPMessage(soapMessage, false);
if(config.isResponseEncryptEnabled()) {
config.isResponseEncryptEnabled(), false);
}
if(config.isResponseSignEnabled()) {
if(!secureMessage.verifySignature()) {
" Verification failed");
throw new SecurityException(
}
}
}
if (LogUtil.isLogEnabled()) {
null);
}
if(debug.messageEnabled()) {
"SOAP message after validation : " +
}
}
/**
* Initialize the system properties before the SAML module is invoked.
*/
throws IOException {
if(debug.messageEnabled()) {
"Provider config does not have keystore information. Will " +
"fallback to the default configuration in AMConfig.");
}
return;
}
}
if(debug.messageEnabled()) {
"Location of the key encrypted password: " + keyPassFile);
}
}
}
"com.sun.identity.wss.provider.defaultWSP", "wsp");
if(debug.messageEnabled()) {
"default provider name:" + providerName);
}
}
try {
"com.sun.identity.wss.provider.defaultWSP", "wsp");
}
} else {
}
if(!config.useDefaultKeyStore()) {
}
} catch (ProviderException pe) {
" configuration read failure", pe);
throw new SecurityException(
} catch (IOException ie) {
" configuration read failure", ie);
throw new SecurityException(
}
return config;
}
try {
"com.sun.identity.wss.provider.defaultWSC", "wsc");
} else {
}
if(!config.useDefaultKeyStore()) {
}
} catch (ProviderException pe) {
" configuration read failure", pe);
throw new SecurityException(
} catch (IOException ie) {
" configuration read failure", ie);
throw new SecurityException(
}
return config;
}
/**
* Returns the security token for the configured security mechanism.
*/
private SecurityToken getSecurityToken(
if(!config.useDefaultKeyStore()) {
}
if(debug.messageEnabled()) {
}
//remove
//uri = SecurityMechanism.WSS_NULL_KERBEROS_TOKEN_URI;
if(debug.messageEnabled()) {
"X509 token");
}
} else if(
if(debug.messageEnabled()) {
"SAML token");
}
if(config.usePassThroughSecurityToken()) {
}
if(securityToken != null) {
if(debug.messageEnabled()) {
"security token from subject is not null");
}
return securityToken;
}
try {
if(debug.messageEnabled()) {
"using thread local for SSOToken");
}
}
} else {
ni = new NameIdentifier(
}
if(attributes != null) {
}
if(config.shouldIncludeMemberships()) {
if(memberships != null) {
}
}
} else {
} else {
ni = new NameIdentifier(
}
}
"Failed in creating SAML tokens", ex);
}
}
if(!samlAttributes.isEmpty()) {
}
}
} else if(
if(debug.messageEnabled()) {
"UserName token");
}
try {
}
if(debug.messageEnabled()) {
"getSubjectSecurity error :"
+ ex.getMessage());
}
}
}
" are configured.");
throw new SecurityException(
}
} else {
}
tokenSpec.setCreateTimeStamp(true);
} else if(
if(debug.messageEnabled()) {
"SAML2 token");
}
if(config.usePassThroughSecurityToken()) {
}
if(securityToken != null) {
if(debug.messageEnabled()) {
"security token from subject is not null");
}
return securityToken;
}
try {
if(debug.messageEnabled()) {
"using thread local for SSOToken");
}
}
if(nameIDMapper == null) {
} else {
}
if(attributes != null) {
}
if(memberships != null) {
}
} else {
} else {
}
}
}
}
if(!samlAttributes.isEmpty()) {
}
}
if(debug.messageEnabled()) {
"Kerberos token");
}
} else {
throw new SecurityException(
}
return securityToken;
}
/**
* Place holder class for the subject credential objects.
*/
private class SubjectSecurity {
}
/**
* Returns the security credentials if exists in the subject.
*/
new PrivilegedAction() {
return null;
}
} else if(credObj instanceof ResourceOffering) {
} else if (
}
}
}
}
return null;
}
});
return subjectSecurity;
}
/**
* Returns the configured message authenticator.
*/
public static MessageAuthenticator getAuthenticator()
throws SecurityException {
if(authenticator != null) {
return authenticator;
}
"com.sun.identity.wss.security.handler.DefaultAuthenticator");
try {
"get the authenticator", ex);
throw new SecurityException(
}
return authenticator;
}
/**
* Returns the configured message authenticator.
*/
public static MessageAuthorizer getAuthorizer()
throws SecurityException {
if(authorizer != null) {
return authorizer;
}
"com.sun.identity.wss.security.handler.DefaultAuthorizer");
try {
"get the authorizer", ex);
throw new SecurityException(
}
return authorizer;
}
/**
* Returns the secured <code>SOAPMessage</code> by using liberty
* protocols.
*
* @param ssoToken Single sign-on token of the user.
*
* @param subject the subject.
*
* @param soapMessage the SOAPMessage that needs to be secured.
*
* @param sharedData any shared data map between request and the response.
*
* @param providerConfig the provider configuration.
*
* @return SecurityException if there is any error occured.
*/
private SOAPMessage getSecureMessageFromLiberty(
throws SecurityException {
try {
if(debug.messageEnabled()) {
}
} catch (SSOException se) {
"Invalid sso token", se);
throw new SecurityException(
} catch (SOAPBindingException sbe) {
" SOAPBinding exception", sbe);
}
}
/**
* Returns the discovery service resource offering.
*/
if(debug.messageEnabled()) {
+ " subject contains resource offering.");
}
return subjectSecurity.discoRO;
}
// If the creds not present, authenticate to the IDP via AuthnService.
if(saslResponse == null) {
"SASL Response is null");
throw new SecurityException(
}
throw new SecurityException(
}
new PrivilegedAction() {
try {
new SecurityAssertion(elem);
if(debug.warningEnabled()) {
"getDiscoveryResourceOffering: ", ex);
}
}
if(assertions != null &&
!assertions.isEmpty()) {
}
}
}
return null;
}
}
);
}
return discoRO;
}
/**
* Returns the credentials for the discovery service.
*/
return subjectSecurity.discoCredentials;
}
/**
* Returns the <code>SASLResponse</code> using user's SSOToken.
*/
throws SecurityException {
try {
" not present in the configuration.");
throw new SecurityException(
}
throw new SecurityException(
}
throw new SecurityException(
}
return saslResp;
} catch (AuthnSvcException ae) {
throw new SecurityException(
} catch (UnsupportedEncodingException uae) {
throw new SecurityException(
}
}
/**
* Checks if the received SOAP Message is a liberty request.
*/
throws SecurityException {
try {
getEnvelope().getHeader();
if(soapHeader == null) {
return false;
}
if((headerChildNodes == null) ||
return false;
}
continue;
}
currentNode.getLocalName())) &&
currentNode.getNamespaceURI()))) {
return true;
}
}
return false;
} catch (SOAPException se) {
}
}
/**
* Returns the provider config from the shared state.
*/
return null;
}
try {
if(serviceName == null) {
if(debug.messageEnabled()) {
"Service Name from javax.xml.ws.wsdl.service : "
+ serviceName);
}
} else {
// If we find the service name, that is of TA service name
// So, create provider config from TA.
if(debug.messageEnabled()) {
"Service Name found in thread local" + serviceName);
}
pc.setDefaultKeyStore(true);
return pc;
}
ProviderConfig.WSC)) {
return null;
}
if(!config.useDefaultKeyStore()) {
}
return config;
} catch (ProviderException pe) {
"shared map: Exception", pe);
return null;
} catch (IOException ie) {
"shared map: IOException", ie);
return null;
}
}
// Check first if thread local has the service name.
return null;
}
return null;
}
return service.getLocalPart();
}
/**
* Prints a Node tree recursively.
*
* @param node A DOM tree Node
*
* @return An xml String representation of the DOM tree.
*/
}
// Removes the validated headers.
try {
} catch (SOAPException se) {
"Failed to read the SOAP Header.");
}
if("Security".equalsIgnoreCase(
}
}
if ("Correlation".equalsIgnoreCase(
}
}
}
}
throws SecurityException {
return null;
}
try {
pc.setPreserveSecurityHeader(false);
return pc;
} catch (ProviderException pe) {
}
}
throws SecurityException {
}
}
continue;
}
continue;
}
continue;
}
try {
}
"FromSubject:: exception", ex);
}
}
return securityToken;
}
private Subject getAuthenticatedSubject() {
return null;
}
return subject;
}
return null;
}
/**
* Retrieves the custom credential from the Subject.
* The custom subject is used as on behalf of token element to the STS.
* @param subject the authenticated JAAS subject where the custom token
* is set.
* @return the custom token object.
*/
return null;
}
continue;
}
}
}
return null;
}
if(debug.messageEnabled()) {
"SSOToken. ssotoken is null");
}
return null;
}
try {
"com.sun.identity.wss.security.useHashedPassword", "true"));
if(useHashedPassword) {
} else {
if(encryptedPassword == null) {
if(debug.messageEnabled()) {
"FromSSOToken. encrypted password is null");
}
return null;
}
}
if(debug.messageEnabled()) {
"FromSSOToken. password is null");
}
return null;
}
return list;
}
} catch (SSOException se) {
if(debug.warningEnabled()) {
"FromSSOToken. ssoexception", se);
}
return null;
}
return null;
}
return false;
}
}
if((prevMsgIDTime != null) &&
"replay attack detected");
}
return true;
} else {
}
}
return false;
}
}
if(object instanceof X509Certificate) {
}
}
//Check if thread local has it.
if(clientCert != null) {
}
}
}
}