FileDocCategorySizeDatePackage
BaseAuthConfig.javaAPI DocGlassfish v2 API23771Fri May 04 22:35:36 BST 2007com.sun.enterprise.security.jauth

BaseAuthConfig

public class BaseAuthConfig extends Object
This class is the container's base interface to the AuthConfig subsystem to get AuthContext objects on which to invoke message layer authentication providers. It is not intended to be layer or web services specific (see getMechanisms method at end). The ServerAuthConfig and ClientAuthConfig classes extend this class.

Fields Summary
private static Logger
logger
private Object
defaultContext_
private com.sun.enterprise.deployment.runtime.common.MessageSecurityDescriptor
superMSD_
private int
superIndex_
private ArrayList
contexts_
private ArrayList
messageSecurityDescriptors_
private ArrayList
contextsForOpcodes_
private HashMap
contextsForOpNames_
private boolean
onePolicy_
private Object
contextLock
private ExplicitNull
explicitNull
private static QName[]
mechanisms
Constructors Summary
protected BaseAuthConfig(Object context)


       

	defaultContext_ = context;
	superMSD_ = null;
	superIndex_ = -1;

	messageSecurityDescriptors_ = null;
	contexts_ = null;
	contextsForOpcodes_ = null;
	contextsForOpNames_ = null;
	
	onePolicy_ = true;

	if(logger.isLoggable(Level.FINE)){
	    logger.fine("WSS: New BAC defaultContext: " + defaultContext_);
	}
    
protected BaseAuthConfig(ArrayList descriptors, ArrayList authContexts)


	defaultContext_ = null;
	superMSD_ = null;
	superIndex_ = -1;

	messageSecurityDescriptors_ = descriptors;
	contexts_ = authContexts;
	contextsForOpcodes_ = null;
	contextsForOpNames_ = null;

	onePolicy_ = true;

	for (int i = 0; i < descriptors.size(); i++) {

	    MessageSecurityDescriptor msd = 
		(MessageSecurityDescriptor) descriptors.get(i);

	    // determine if all the different messageSecurityDesriptors have the
	    // same policy which will help us interpret the effective policy if
	    // we cannot determine the opcode of a request at runtime.

	    for (int j = 0; j < descriptors.size(); j++) {
		if (j != i && !policiesAreEqual
		    (msd,((MessageSecurityDescriptor) descriptors.get(j)))) {
		    onePolicy_ = false;
		}
	    }
	}

	for (int i = 0; defaultContext_ == null && i < descriptors.size(); i++) {

	    MessageSecurityDescriptor msd = (MessageSecurityDescriptor) descriptors.get(i);

	    AuthPolicy requestPolicy = 
		getAuthPolicy(msd.getRequestProtectionDescriptor());

	    AuthPolicy responsePolicy = 
		getAuthPolicy(msd.getResponseProtectionDescriptor());

	    boolean noProtection = (!requestPolicy.authRequired() && 
				    !responsePolicy.authRequired());

	    // if there is one policy, and it is null set the associated context as the
	    // defaultContext used for all messages.
	    if (i==0 && onePolicy_ && noProtection) {
		defaultContext_ = explicitNull;
		break;
	    }

	    ArrayList mDs = msd.getMessageDescriptors();

	    for (int j=0; mDs != null && j < mDs.size(); j++) {
		
		MessageDescriptor mD = (MessageDescriptor) mDs.get(j);
		MethodDescriptor methD = mD.getMethodDescriptor();

		// if any msd covers all methods and operations.
		if ((mD.getOperationName() == null && methD == null) ||
                        (methD != null && methD.getStyle() == 1)) {

		    if (onePolicy_) {
			// if there is only one policy make it the default.
			defaultContext_ = contexts_.get(i);
			if (defaultContext_ == null) {
			    defaultContext_ = explicitNull;
			}
			break;
		    } else if (superIndex_ == -1) {
			// if it has a noProtection policy make it the default.
			if (noProtection) {
			    defaultContext_ = explicitNull;
			} else {
			    superIndex_ = i;
			}
		    } else if (!policiesAreEqual(msd,((MessageSecurityDescriptor) 
						      descriptors.get(superIndex_)))) {
			// if there are conflicting policies that cover all methods
			// set the default policy to noProtection
			defaultContext_ = explicitNull;
			superIndex_ = -1;
			break;
		    }
		}
	    }
	}
	// if there is protected policy that applies to all methods remember the descriptor.
	// Note that the corresponding policy is not null, and thus it is not the default.
	// wherever there is a conflicting policy the effective policy will be noProtection.
	if (superIndex_ >=0) {
	    superMSD_ = (MessageSecurityDescriptor) descriptors.get(superIndex_);
	}

	if(logger.isLoggable(Level.FINE)){
	    logger.fine("WSS: new BAC defaultContext_: " + defaultContext_ +
			" superMSD index: " + superIndex_ + " onePolicy_: " + onePolicy_);
	}
    
Methods Summary
protected static com.sun.enterprise.security.jauth.AuthPolicygetAuthPolicy(com.sun.enterprise.deployment.runtime.common.ProtectionDescriptor pd)

	int sourceAuthType = AuthPolicy.SOURCE_AUTH_NONE;
	boolean recipientAuth = false;
	boolean beforeContent = false;
	if (pd != null) {
	    String source = pd.getAttributeValue
		(ProtectionDescriptor.AUTH_SOURCE);
	    if (source != null) { 
		if (source.equals(AuthPolicy.SENDER)) {
		    sourceAuthType = AuthPolicy.SOURCE_AUTH_SENDER;
		} else if (source.equals(AuthPolicy.CONTENT)) {
		    sourceAuthType = AuthPolicy.SOURCE_AUTH_CONTENT;
		}
	    }
	    String recipient = pd.getAttributeValue
		(ProtectionDescriptor.AUTH_RECIPIENT);
	    if (recipient != null) { 
		recipientAuth = true;
		if (recipient.equals(AuthPolicy.BEFORE_CONTENT)) {
		    beforeContent = true;
		} else if (recipient.equals(AuthPolicy.AFTER_CONTENT)) {
		    beforeContent = false;
		}
	    }
	}
	return new AuthPolicy(sourceAuthType,recipientAuth,beforeContent);
    
protected java.lang.ObjectgetContext(com.sun.xml.rpc.spi.runtime.StreamingHandler handler, javax.xml.soap.SOAPMessage message)


	Object rvalue = null;

	synchronized(contextLock) {
	    if (defaultContext_ != null) { 
		rvalue = defaultContext_;
	    }
	}
 
	if (rvalue == null) {

	    if (handler == null) {

		// lack of handler precludes mapping to opcode, so we will
		// look for an opName based mapping.

		rvalue = getContextForMessage(message);

	    } else {

		int opCode = handler.getOpcodeForRequestMessage(message);

		if (opCode == -1) {

		    // msg body is encrypted, and the best we can do is try 
		    // to return a policy that applies to all opcodes.

		    rvalue = getContextForMethod(null);

		} else {
		    
		    try {
			rvalue = getExplicitContextForOpCode(handler,opCode);
		    
			// if unable to get context by opcode 
			// see if a context was defined for the opName.
		    
			if (rvalue == null) {

			    rvalue = getContextForMessage(message);

			}
		    } catch (ClassNotFoundException cnfe) {
			throw new RuntimeException(cnfe);
		    } catch (NoSuchMethodException nsme) {
			throw new RuntimeException(nsme);
		    }
		}
	    }
	}

	if (rvalue != null && rvalue instanceof ExplicitNull) {
	    rvalue = null;
	}

	if(logger.isLoggable(Level.FINE)){
	    logger.fine("WSS: getContext returning: " + rvalue);
	}

	return rvalue;
    
protected java.lang.ObjectgetContext(javax.xml.ws.handler.soap.SOAPMessageContext soapMC)


	Object rvalue = null;

	synchronized(contextLock) {
	    if (defaultContext_ != null) { 
		rvalue = defaultContext_;
	    }
	}

	if (rvalue == null) {

	    Method m = getMethod(soapMC);
	    String opName = null;

	    if (m != null) {
		rvalue = getContextForMethod(m);
	    }

	    if (rvalue == null) {
		opName = getOpName(soapMC);
		if (opName != null) {
		    rvalue = getContextForOpName(opName);
		}
	    }

	    if (rvalue == null && (m == null || opName == null)) {

		//we were unable to determine either method or
		// opName, so lets see if one policy applies to all

		rvalue = getContextForMethod(null);
	    }
	}
	
	if (rvalue != null && rvalue instanceof ExplicitNull) {
	    rvalue = null;
	}

	return rvalue;
    
private java.lang.ObjectgetContextForMessage(javax.xml.soap.SOAPMessage message)

	
	String opName = getOpName(message);

	Object rvalue = getContextForOpName(opName);
	if (rvalue == null) {

	    // opName is not mapped or msg body is encrypted, and the best 
	    // we can do is try to return a policy that applies to all 
	    // operations, if there is one.
	    
	    rvalue = getContextForMethod(null);

	}
	return rvalue;
    
private java.lang.ObjectgetContextForMethod(java.lang.reflect.Method m)

	Object rvalue = null;
	synchronized(contextLock) {
	    if (defaultContext_ != null) { 
		rvalue = defaultContext_;
		if(logger.isLoggable(Level.FINE)){
		    logger.fine("WSS: ForMethod returning default_context: " + rvalue);
		}
		return rvalue;
	    }
	}
	if (m != null) {
	    int match = -1;
	    MethodDescriptor targetMD = new MethodDescriptor(m);
	    for (int i = 0; i < messageSecurityDescriptors_.size(); i++) {
		if (isMatchingMSD(targetMD,(MessageSecurityDescriptor) 
				  messageSecurityDescriptors_.get(i))) {
		    if (match < 0) { 
			match = i;
		    } else if (!policiesAreEqual
			       ((MessageSecurityDescriptor) 
				messageSecurityDescriptors_.get(match),
				(MessageSecurityDescriptor)
				messageSecurityDescriptors_.get(i))) {

			// set to unprotected because of conflicting policies

			rvalue = explicitNull;
			match = -1;
			if(logger.isLoggable(Level.FINE)){
			    logger.fine("WSS: ForMethod detected conflicting policies: " + 
					match + "." + i);
			}
			break;
		    }
		}
	    }
	    if (match >= 0) {
		rvalue = contexts_.get(match);
		if (rvalue == null) {
		    rvalue = explicitNull;
		}
		if(logger.isLoggable(Level.FINE)){
		    logger.fine("WSS: ForMethod returning matched context: " + rvalue);
		}
	    }
	} else if (onePolicy_ && contexts_.size() > 0) {
 	    // ISSUE: since the method is undefined we will not be 
	    // able to tell if the defined policy covers this method.
 	    // We will be optimistic and try the policy, because
 	    // the server will reject the call if the method is not
 	    // covered by the policy.
 	    // If the policy is not null, there remains a problem at the 
	    // client on the response side, as it is possible that the 
	    // client will enforce the wrong policy on the response.
 	    // For this reason, messages in sun-application-client.xml 
	    // should be keyed by operation-name.

	    rvalue = contexts_.get(0);
	    if(logger.isLoggable(Level.FINE)){
		logger.fine("WSS: ForMethod resorting to first context: " + rvalue);
	    }
 
	} else {
	    if(logger.isLoggable(Level.FINE)){
	        logger.fine("WSS: Unable to select policy for SOAP Message");
            }
	    throw new RuntimeException("Unable to select policy for Message");
	}
	return rvalue;
    
protected java.lang.ObjectgetContextForOpCode(com.sun.xml.rpc.spi.runtime.StreamingHandler handler, int opcode)

	Object rvalue = getExplicitContextForOpCode(handler,opcode);
	if (rvalue != null && rvalue instanceof ExplicitNull) {
	    rvalue = null;
	}
	return rvalue;
    
private java.lang.ObjectgetContextForOpName(java.lang.String operation)


	synchronized(contextLock) {
	    if (contextsForOpNames_ == null) {

		// one time initialization of the opName to authContext array.

		contextsForOpNames_ = new HashMap();
		for (int i=0; messageSecurityDescriptors_ != null &&
			 i < messageSecurityDescriptors_.size(); i++) {
		    
		    MessageSecurityDescriptor mSD = (MessageSecurityDescriptor)
			messageSecurityDescriptors_.get(i);

		    ArrayList mDs = mSD.getMessageDescriptors();

		    for (int j=0; mDs != null && j < mDs.size(); j++) {

			MessageDescriptor mD = (MessageDescriptor) mDs.get(j);
			String opName = mD.getOperationName();

			if (opName != null) {

			    if (contextsForOpNames_.containsKey(opName)) {

				Integer k = (Integer) contextsForOpNames_.get(opName);
				if (k != null) {

				    MessageSecurityDescriptor other =
					(MessageSecurityDescriptor)
					messageSecurityDescriptors_.get(k.intValue());

				    // set to null if different policies on operation

				    if (!policiesAreEqual(mSD,other)) {
					contextsForOpNames_.put(opName,null);
				    }
				}
			    } else if (superMSD_!=null && !policiesAreEqual(mSD,superMSD_)){
				// set to null if operation policy differs from superPolicy
				contextsForOpNames_.put(opName,null);
			    } else {
				contextsForOpNames_.put(opName,new Integer(i));
			    }
			}
		    }
		}
	    }
	}

	Object rvalue = null; 
	if (operation != null) {
	    if (contextsForOpNames_.containsKey(operation)) {
		Integer k = (Integer) contextsForOpNames_.get(operation);
		if (k != null) {
		    rvalue = contexts_.get(k.intValue());
		} 
	    } else if (superIndex_ >= 0) {
                // if there is a msb that matches all methods, use the
                // associatedContext
                rvalue = contexts_.get(superIndex_);
	    }

            if (rvalue == null) {
                // else return explicitNull under the assumption
                // that methodName was known, and no match was found 
                rvalue = explicitNull;
            }
            if (logger.isLoggable(Level.FINE)) {
                logger.fine("WSS: ForOpName=" + operation + " context: " + rvalue);
            }
	} 
	return rvalue;
    
private java.lang.ObjectgetExplicitContextForOpCode(com.sun.xml.rpc.spi.runtime.StreamingHandler handler, int opcode)


	Object rvalue = null;

	synchronized(contextLock) {

	    if (contextsForOpcodes_ == null && defaultContext_ == null) {

		// one time initialization of the opcode to authContext array.

		boolean onePolicyForAll = onePolicy_;

		Method m = null;
		for (int i = 0; i == 0 || m != null; i++) {
		    if (i == 0) {
			contextsForOpcodes_ = new ArrayList();
		    }
		    if (handler != null) {
			m = handler.getMethodForOpcode(i);
		    }
		    if (m != null) {
			Object o = getContextForMethod(m);
			contextsForOpcodes_.add(o);

			// if we find a method that is not covered by a method
			// descriptor (i.e. has an implicit nullPolicy), 
			// then we switch off onePolicyForAll (note that 
			// ServerAuthConfigs with one policy being the
			// null policy, are not constructed.

			if (o == null) {
			    onePolicyForAll = false;
			}
		    }
		}
		if (onePolicyForAll && contextsForOpcodes_.size() > 0) {
		    defaultContext_ = contextsForOpcodes_.get(0);
		}
	    }
	    if (defaultContext_ != null) {
		rvalue = defaultContext_;
		if(logger.isLoggable(Level.FINE)){
		    logger.fine("WSS: ForOpCode returning default_context: " + rvalue);
		}
	    }
	}

	if (rvalue == null) {
	    if (opcode >=0 && opcode < contextsForOpcodes_.size()) {
		rvalue = contextsForOpcodes_.get(opcode);
	    } else if (opcode < 0) {
		//we don't know the opcode, so lets try to see if
		//there is a policy that applies to all opcodes.
		rvalue = getContextForMethod(null);
	    }
	}
	return rvalue;
    
public javax.xml.namespace.QName[]getMechanisms()

	return mechanisms;
    
public static java.lang.reflect.MethodgetMethod(javax.xml.ws.handler.soap.SOAPMessageContext soapMC)


        // It should never come here
	return null;
    
private static javax.xml.soap.NamegetName(javax.xml.soap.SOAPMessage message)

	Name rvalue = null;
	SOAPPart soap = message.getSOAPPart();
	if (soap != null) {
	    try {
		SOAPEnvelope envelope = soap.getEnvelope(); 
		if (envelope != null) {
		    SOAPBody body = envelope.getBody();
		    if (body != null) {
			Iterator it = body.getChildElements();
			while (it.hasNext()) {
			    Object o = it.next();
			    if (o instanceof SOAPElement) {
				rvalue = ((SOAPElement) o).getElementName(); 
				break;
			    }
			}
		    }
		}
	    } catch (SOAPException se) {
		if(logger.isLoggable(Level.FINE)){
		    logger.log(Level.FINE,"WSS: Unable to get SOAP envelope",
			       se);
		}
	    }
	}
	
	return rvalue;
    
private static java.lang.StringgetOpName(javax.xml.soap.SOAPMessage message)


	String rvalue = null;

	// first look for a SOAPAction header. 
	// this is what .net uses to identify the operation

	MimeHeaders headers = message.getMimeHeaders();
	if (headers != null) {
	    String[] actions = headers.getHeader("SOAPAction");
	    if (actions != null && actions.length > 0) {
		rvalue = actions[0];
		if (rvalue != null && rvalue.equals("\"\"")) {
		    rvalue = null;
		}
	    }
	} 

	// if that doesn't work then we default to trying the name
	// of the first child element of the SOAP envelope.

	if (rvalue == null) {
	    Name name = getName(message);
	    if (name != null) {
		rvalue = name.getLocalName();
	    }
	}
	
	return rvalue;
    
private static java.lang.StringgetOpName(javax.xml.ws.handler.soap.SOAPMessageContext soapMC)


	String rvalue = null;

	// first look for a the property value in the context
	QName qName = (QName) soapMC.get(MessageContext.WSDL_OPERATION);
	if (qName != null) {
	    rvalue = qName.getLocalPart();
	} else {
	    rvalue = getOpName(WsUtil.getMessageWithName(soapMC));
	}

	return rvalue;
    
private static booleanisMatchingMSD(com.sun.enterprise.deployment.MethodDescriptor targetMD, com.sun.enterprise.deployment.runtime.common.MessageSecurityDescriptor mSD)

	ArrayList messageDescriptors = mSD.getMessageDescriptors();
	if (messageDescriptors.size() == 0) {
	    // If this happens the dd is invalid.
	    // Unfortunately the deployment system does not catch such problems.
	    // This case will be treated the same as if there was an empty message
	    // element, and the deployment will be allowed to succeed.
	    return true;
	}

	for (int i=0; i<messageDescriptors.size(); i++) {
	    MessageDescriptor nextMD = 
		(MessageDescriptor) messageDescriptors.get(i);
	    MethodDescriptor mD = nextMD.getMethodDescriptor();
	    String opName = nextMD.getOperationName();

	    if (opName == null && (mD == null || mD.implies(targetMD))){
		return true;
	    }
	}

	return false;
    
private booleanmethodIsCovered(java.lang.reflect.Method m)

	boolean rvalue = true; 
	if (messageSecurityDescriptors_ != null) {
	    MethodDescriptor targetMD = new MethodDescriptor(m);
	    for (int i = 0; i < messageSecurityDescriptors_.size(); i++) {
		if (i == 0) {
		    rvalue = false;
		}
		if (isMatchingMSD(targetMD,(MessageSecurityDescriptor) 
				  messageSecurityDescriptors_.get(i))) {
		    rvalue = true;
		    break;
		}
	    }
	}
	return rvalue;
    
private static booleanpoliciesAreEqual(com.sun.enterprise.deployment.runtime.common.MessageSecurityDescriptor reference, com.sun.enterprise.deployment.runtime.common.MessageSecurityDescriptor other)

	if (!getAuthPolicy
	    (reference.getRequestProtectionDescriptor()).equals
	    (getAuthPolicy(other.getRequestProtectionDescriptor())) ||

	    !getAuthPolicy
	    (reference.getResponseProtectionDescriptor()).equals
	    (getAuthPolicy(other.getResponseProtectionDescriptor()))) {
	    
	    return false;
	}
	return true;