Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* 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.apache.rampart;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultCode;
import org.apache.axiom.soap.SOAPFaultSubCode;
import org.apache.axiom.soap.SOAPFaultValue;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.Token;
import org.apache.rahas.TokenStorage;
import org.apache.rahas.TrustUtil;
import org.apache.rahas.impl.util.SAML2KeyInfo;
import org.apache.rahas.impl.util.SAML2Utils;
import org.apache.rampart.policy.RampartPolicyData;
import org.apache.rampart.util.Axis2Util;
import org.apache.rampart.util.RampartUtil;
import org.apache.ws.secpolicy.WSSPolicyException;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSSecurityEngine;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.WSUsernameTokenPrincipal;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.saml.SAMLKeyInfo;
import org.apache.ws.security.saml.SAMLUtil;
import org.opensaml.SAMLAssertion;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Conditions;
import org.opensaml.saml2.core.Subject;
import org.opensaml.saml2.core.SubjectConfirmationData;
import javax.xml.namespace.QName;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Vector;
public class RampartEngine {
private static Log log = LogFactory.getLog(RampartEngine.class);
private static Log tlog = LogFactory.getLog(RampartConstants.TIME_LOG);
private static ServiceNonceCache serviceNonceCache = new ServiceNonceCache();
public Vector process(MessageContext msgCtx) throws WSSPolicyException,
RampartException, WSSecurityException, AxisFault {
boolean doDebug = log.isDebugEnabled();
boolean dotDebug = tlog.isDebugEnabled();
log.debug("Enter process(MessageContext msgCtx)");
RampartMessageData rmd = new RampartMessageData(msgCtx, false);
RampartPolicyData rpd = rmd.getPolicyData();
msgCtx.setProperty(RampartMessageData.RAMPART_POLICY_DATA, rpd);
RampartUtil.validateTransport(rmd);
// If there is no policy information return immediately
if (rpd == null) {
return null;
}
//TODO these checks have to be done before the convertion to avoid unnecessary convertion to LLOM -> DOOM
// If the message is a security fault or no security
// header required by the policy
if(isSecurityFault(rmd) || !RampartUtil.isSecHeaderRequired(rpd,rmd.isInitiator(),true)) {
SOAPEnvelope env = Axis2Util.getSOAPEnvelopeFromDOMDocument(rmd.getDocument(), true);
//Convert back to llom since the inflow cannot use llom
msgCtx.setEnvelope(env);
Axis2Util.useDOOM(false);
log.debug("Return process MessageContext msgCtx)");
return null;
}
Vector results = null;
WSSecurityEngine engine = new WSSecurityEngine();
ValidatorData data = new ValidatorData(rmd);
SOAPHeader header = rmd.getMsgContext().getEnvelope().getHeader();
if(header == null) {
throw new RampartException("missingSOAPHeader");
}
ArrayList headerBlocks = header.getHeaderBlocksWithNSURI(WSConstants.WSSE_NS);
SOAPHeaderBlock secHeader = null;
//Issue is axiom - a returned collection must not be null
if(headerBlocks != null) {
Iterator headerBlocksIterator = headerBlocks.iterator();
while (headerBlocksIterator.hasNext()) {
SOAPHeaderBlock elem = (SOAPHeaderBlock) headerBlocksIterator.next();
if(elem.getLocalName().equals(WSConstants.WSSE_LN)) {
secHeader = elem;
break;
}
}
}
if(secHeader == null) {
throw new RampartException("missingSecurityHeader");
}
long t0=0, t1=0, t2=0, t3=0;
if(dotDebug){
t0 = System.currentTimeMillis();
}
String actorValue = secHeader.getAttributeValue(new QName(rmd
.getSoapConstants().getEnvelopeURI(), "actor"));
Crypto signatureCrypto = RampartUtil.getSignatureCrypto(rpd.getRampartConfig(),
msgCtx.getAxisService().getClassLoader());
TokenCallbackHandler tokenCallbackHandler = new TokenCallbackHandler(rmd.getTokenStorage(), RampartUtil.getPasswordCB(rmd));
if(rpd.isSymmetricBinding()) {
//Here we have to create the CB handler to get the tokens from the
//token storage
log.debug("Processing security header using SymetricBinding");
results = engine.processSecurityHeader(rmd.getDocument(),
actorValue,
tokenCallbackHandler,
signatureCrypto,
RampartUtil.getEncryptionCrypto(rpd.getRampartConfig(),
msgCtx.getAxisService().getClassLoader()));
// Remove encryption tokens if this is the initiator and if initiator is receiving a message
if (rmd.isInitiator() && (msgCtx.getFLOW() == MessageContext.IN_FLOW ||
msgCtx.getFLOW() == MessageContext.IN_FAULT_FLOW)) {
tokenCallbackHandler.removeEncryptedToken();
}
} else {
log.debug("Processing security header in normal path");
results = engine.processSecurityHeader(rmd.getDocument(),
actorValue,
tokenCallbackHandler,
signatureCrypto,
RampartUtil.getEncryptionCrypto(rpd.getRampartConfig(),
msgCtx.getAxisService().getClassLoader()));
}
if(dotDebug){
t1 = System.currentTimeMillis();
}
//Store symm tokens
//Pick the first SAML token
//TODO : This is a hack , MUST FIX
//get the sec context id from the req msg ctx
//Store username in MessageContext property
for (int j = 0; j < results.size(); j++) {
WSSecurityEngineResult wser = (WSSecurityEngineResult) results.get(j);
final Integer actInt =
(Integer) wser.get(WSSecurityEngineResult.TAG_ACTION);
if (WSConstants.ST_UNSIGNED == actInt.intValue()) {
// If this is a SAML2.0 assertion
if (wser.get(WSSecurityEngineResult.TAG_SAML_ASSERTION) instanceof Assertion) {
final Assertion assertion = (Assertion) wser.get(
WSSecurityEngineResult.TAG_SAML_ASSERTION);
// if the subject confirmation method is Bearer, do not try to get the KeyInfo
if(TrustUtil.getSAML2SubjectConfirmationMethod(assertion).equals(
RahasConstants.SAML20_SUBJECT_CONFIRMATION_BEARER)){
break;
}
String id = assertion.getID();
Subject subject = assertion.getSubject();
Date dateOfCreation = null;
Date dateOfExpiration = null;
//Read the validity period from the 'Conditions' element, else read it from SC Data
if (assertion.getConditions() != null) {
Conditions conditions = assertion.getConditions();
if (conditions.getNotBefore() != null) {
dateOfCreation = conditions.getNotBefore().toDate();
}
if (conditions.getNotOnOrAfter() != null) {
dateOfExpiration = conditions.getNotOnOrAfter().toDate();
}
} else {
SubjectConfirmationData scData = subject.getSubjectConfirmations()
.get(0).getSubjectConfirmationData();
if (scData.getNotBefore() != null) {
dateOfCreation = scData.getNotBefore().toDate();
}
if (scData.getNotOnOrAfter() != null) {
dateOfExpiration = scData.getNotOnOrAfter().toDate();
}
}
// TODO : SAML2KeyInfo element needs to be moved to WSS4J.
SAML2KeyInfo saml2KeyInfo = SAML2Utils.
getSAML2KeyInfo(assertion, signatureCrypto, tokenCallbackHandler);
//Store the token
try {
TokenStorage store = rmd.getTokenStorage();
if (store.getToken(id) == null) {
Token token = new Token(id, (OMElement) SAML2Utils.getElementFromAssertion(assertion), dateOfCreation, dateOfExpiration);
token.setSecret(saml2KeyInfo.getSecret());
store.add(token);
}
} catch (Exception e) {
throw new RampartException(
"errorInAddingTokenIntoStore", e);
}
}
//if this is a SAML1.1 assertion
else {
final SAMLAssertion assertion = ((SAMLAssertion) wser.get(
WSSecurityEngineResult.TAG_SAML_ASSERTION));
// if the subject confirmation method is Bearer, do not try to get the KeyInfo
if(RahasConstants.SAML11_SUBJECT_CONFIRMATION_BEARER.equals(
TrustUtil.getSAML11SubjectConfirmationMethod(assertion))){
break;
}
String id = assertion.getId();
Date created = assertion.getNotBefore();
Date expires = assertion.getNotOnOrAfter();
SAMLKeyInfo samlKi = SAMLUtil.getSAMLKeyInfo(assertion,
signatureCrypto, tokenCallbackHandler);
try {
TokenStorage store = rmd.getTokenStorage();
if (store.getToken(id) == null) {
Token token = new Token(id, (OMElement) assertion.toDOM(), created, expires);
token.setSecret(samlKi.getSecret());
store.add(token);
}
} catch (Exception e) {
throw new RampartException(
"errorInAddingTokenIntoStore", e);
}
}
} else if (WSConstants.UT == actInt.intValue()) {
WSUsernameTokenPrincipal userNameTokenPrincipal = (WSUsernameTokenPrincipal)wser.get(WSSecurityEngineResult.TAG_PRINCIPAL);
String username = userNameTokenPrincipal.getName();
msgCtx.setProperty(RampartMessageData.USERNAME, username);
if (userNameTokenPrincipal.getNonce() != null) {
// Check whether this is a replay attack. To verify that we need to check whether nonce value
// is a repeating one
int nonceLifeTimeInSeconds = 0;
if (rpd.getRampartConfig() != null) {
String stringLifeTime = rpd.getRampartConfig().getNonceLifeTime();
try {
nonceLifeTimeInSeconds = Integer.parseInt(stringLifeTime);
} catch (NumberFormatException e) {
log.error("Invalid value for nonceLifeTime in rampart configuration file.", e);
throw new RampartException(
"invalidNonceLifeTime", e);
}
}
String serviceEndpointName = msgCtx.getAxisService().getEndpointName();
boolean valueRepeating = serviceNonceCache.isNonceRepeatingForService(serviceEndpointName, username, userNameTokenPrincipal.getNonce());
if (valueRepeating){
throw new RampartException("repeatingNonceValue", new Object[]{ userNameTokenPrincipal.getNonce(), username} );
}
serviceNonceCache.addNonceForService(serviceEndpointName, username, userNameTokenPrincipal.getNonce(), nonceLifeTimeInSeconds);
}
} else if (WSConstants.SIGN == actInt.intValue()) {
X509Certificate cert = (X509Certificate) wser.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
msgCtx.setProperty(RampartMessageData.X509_CERT, cert);
}
}
SOAPEnvelope env = Axis2Util.getSOAPEnvelopeFromDOMDocument(rmd.getDocument(), true);
if(dotDebug){
t2 = System.currentTimeMillis();
}
//Convert back to llom since the inflow cannot use DOOM
msgCtx.setEnvelope(env);
Axis2Util.useDOOM(false);
PolicyValidatorCallbackHandler validator = RampartUtil.getPolicyValidatorCB(msgCtx, rpd);
validator.validate(data, results);
if(dotDebug){
t3 = System.currentTimeMillis();
tlog.debug("processHeader by WSSecurityEngine took : " + (t1 - t0) +
", DOOM conversion took :" + (t2 - t1) +
", PolicyBasedResultsValidattor took " + (t3 - t2));
}
log.debug("Return process(MessageContext msgCtx)");
return results;
}
// Check whether this a soap fault because of failure in processing the security header
//and if so, we don't expect the security header
//
//
private boolean isSecurityFault(RampartMessageData rmd) {
SOAPEnvelope soapEnvelope = rmd.getMsgContext().getEnvelope();
SOAPFault soapFault = soapEnvelope.getBody().getFault();
// This is not a soap fault
if (soapFault == null) {
return false;
}
String soapVersionURI = rmd.getMsgContext().getEnvelope().getNamespace().getNamespaceURI();
SOAPFaultCode faultCode = soapFault.getCode();
if(faultCode == null){
//If no fault code is given, then it can't be security fault
return false;
}
if (soapVersionURI.equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
// This is a fault processing the security header
if (faultCode.getTextAsQName().getNamespaceURI().equals(WSConstants.WSSE_NS)) {
return true;
}
} else if (soapVersionURI.equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
// TODO AXIOM API returns only one fault sub code, there can be many
SOAPFaultSubCode faultSubCode = faultCode.getSubCode();
if (faultSubCode != null) {
SOAPFaultValue faultSubCodeValue = faultSubCode.getValue();
// This is a fault processing the security header
if (faultSubCodeValue != null && faultSubCodeValue.getTextAsQName().
getNamespaceURI().equals(WSConstants.WSSE_NS)) {
return true;
}
}
}
return false;
}
}