FileDocCategorySizeDatePackage
SecurityServiceImpl.javaAPI DocGlassfish v2 API12297Fri May 04 22:34:58 BST 2007com.sun.enterprise.iiop.security

SecurityServiceImpl

public class SecurityServiceImpl extends Object implements SecurityService
This class provides the implementation of the SPI between the CSIV2 layer and the RI.
author
Vivek Nagar
author
Harpreet Singh

Fields Summary
private static Logger
_logger
private static String
IS_A
private Policy
policy
Constructors Summary
public SecurityServiceImpl()



      

	policy = Policy.getPolicy();
    
Methods Summary
private voidauthenticate(javax.security.auth.Subject s, java.lang.Class cls)
Authenticate the user with the specified subject and credential class.

        // authenticate
        try {
            final Subject fs = s;
            final Class cl = cls;
            AccessController.doPrivileged(new PrivilegedAction() {
                public java.lang.Object run() {
                    LoginContextDriver.login(fs, cl);
                    return null;
                }
            });
        } catch(Exception e) {
            if(_logger.isLoggable(Level.SEVERE)){
		_logger.log(Level.SEVERE,"iiop.login_exception",e.toString());
            }
            if(_logger.isLoggable(Level.FINE)){
		_logger.log(Level.FINE,"Login Exception",e);
            }
            throw new SecurityMechanismException("Cannot login user:" + 
                        e.getMessage());
        }
    
private booleanauthorizeCORBA(byte[] object_id, java.lang.String method)


	// Check if target is an EJB
        POAProtocolMgr protocolMgr = (POAProtocolMgr)
				    Switch.getSwitch().getProtocolManager();
        // Check to make sure protocolMgr is not null. 
        // This could happen during server initialization or if this call
        // is on a callback object in the client VM. 
        if ( protocolMgr == null )
            return true;

	if ( protocolMgr.getEjbDescriptor(object_id) != null )
	    return true; // an EJB object

	CORBAObjectPermission perm = new CORBAObjectPermission("*", method);

	// Create a ProtectionDomain for principal on current thread.
	com.sun.enterprise.security.SecurityContext sc = 
		    com.sun.enterprise.security.SecurityContext.getCurrent();
        Set principalSet = sc.getPrincipalSet();
	Principal[] principals = (principalSet == null ? null :
                         (Principal []) principalSet.toArray(new Principal[0]));
	CodeSource cs = new CodeSource(new java.net.URL("file://"),  
                            (java.security.cert.Certificate[]) null);
        ProtectionDomain prdm = new ProtectionDomain(cs, null, null, principals);

	// Check if policy gives principal the permissions
	boolean result = policy.implies(prdm, perm);

	if ( _logger.isLoggable(Level.FINE) ) {
	    _logger.log(Level.FINE, "CORBA Object permission evaluation result="
				    + result + " for method=" + method);
	}
	return result;
    
public SecurityContextgetSecurityContext(org.omg.CORBA.Object effective_target)
This is called by the CSIv2 interceptor on the client before sending the IIOP message.

param
the effective_target field of the PortableInterceptor ClientRequestInfo object.
return
a SecurityContext which is marshalled into the IIOP msg by the CSIv2 interceptor.

        SecurityContext context = null;

        IOR ior = ((com.sun.corba.ee.spi.orb.ORB)ORBManager.getORB()).getIOR(effective_target, false);
	if (StubAdapter.isStub(effective_target)) {
	    if (StubAdapter.isLocal(effective_target)) {
		return null;
	    }
	}

        try {
            SecurityMechanismSelector sms = new SecurityMechanismSelector();
            context = sms.selectSecurityContext(ior);
        } catch (InvalidMechanismException ime){ // let this pass ahead
            _logger.log(Level.SEVERE,"iiop.invalidmechanism_exception",ime);
            throw new InvalidMechanismException (ime.getMessage());
        } catch(InvalidIdentityTokenException iite){
           _logger.log(Level.SEVERE,"iiop.invalididtoken_exception",iite);
            throw new InvalidIdentityTokenException(iite.getMessage());
            // let this pass ahead
        } catch(SecurityMechanismException sme) {
           _logger.log(Level.SEVERE,"iiop.secmechanism_exception",sme);
            throw new RuntimeException(sme.getMessage());
        }
        return context;
    
public voidreceivedReply(int reply_status, org.omg.CORBA.Object effective_target)
This is called by the CSIv2 interceptor on the client after a reply is received.

param
the reply status from the call. The reply status field could indicate an authentication retry. The following is the mapping of PI status to the reply_status field PortableInterceptor::SUCCESSFUL -> STATUS_PASSED PortableInterceptor::SYSTEM_EXCEPTION -> STATUS_FAILED PortableInterceptor::USER_EXCEPTION -> STATUS_PASSED PortableInterceptor::LOCATION_FORWARD -> STATUS_RETRY PortableInterceptor::TRANSPORT_RETRY -> STATUS_RETRY
param
the effective_target field of the PI ClientRequestInfo object.

        if(reply_status == STATUS_FAILED) {
            if(_logger.isLoggable(Level.FINE)){
                _logger.log(Level.FINE,"Failed status");
            }
            // what kind of exception should we throw? 
            throw new RuntimeException("Target did not accept security context");
        } else if(reply_status == STATUS_RETRY) {
            if(_logger.isLoggable(Level.FINE)){
		_logger.log(Level.FINE,"Retry status");
            }
        } else {
            if(_logger.isLoggable(Level.FINE)){
		_logger.log(Level.FINE,"Passed status");
            }
        }
    
public voidsendingReply(SecurityContext context)
This is called by the CSIv2 interceptor on the server before sending the reply.

param
the SecurityContext which arrived in the IIOP message.

        // NO OP
    
public intsetSecurityContext(SecurityContext context, byte[] object_id, java.lang.String method)
This is called by the CSIv2 interceptor on the server after receiving the IIOP message. If authentication fails a FAILED status is returned. If a FAILED status is returned the CSIV2 interceptor will marshall the MessageError service context and throw the NO_PERMISSION exception.

param
the SecurityContext which arrived in the IIOP message.
return
the status

        if(_logger.isLoggable(Level.FINE)){
            _logger.log(Level.FINE,"ABOUT TO EVALUATE TRUST");
        }

        try {
	    // First check if the client sent the credentials
	    // as required by the object's CSIv2 policy.
	    // evaluateTrust will throw an exception if client did not
	    // conform to security policy.
            SecurityMechanismSelector sms = new SecurityMechanismSelector();
	    SecurityContext ssc = sms.evaluateTrust(context, object_id); 

	    Class cls = null;
            Subject s = null;
            if(ssc == null) {
                return STATUS_PASSED;
            } else {
                if(ssc.authcls != null) {
                    cls = ssc.authcls;
                } else {
                    cls = ssc.identcls;
                }
                s = ssc.subject;
            }

	    // Authenticate the client. An Exception is thrown if login fails.
	    // SecurityContext is set on current thread if login succeeds.
            authenticate(s, cls);

	    // Authorize the client for non-EJB objects.
	    // Auth for EJB objects is done in BaseContainer.preInvoke().
	    if ( authorizeCORBA(object_id, method) )
		return STATUS_PASSED;
	    else 
		return STATUS_FAILED;

        } catch(Exception e) {
            if (!method.equals(IS_A)){
		if(_logger.isLoggable(Level.FINE)){
                    _logger.log(Level.FINE,"iiop.authenticate_exception",e.toString());
                }
            if(_logger.isLoggable(Level.FINE)){
                    _logger.log(Level.FINE,"Authentication Exception",e);
                }
            }
            return STATUS_FAILED;
        }
    
public voidunsetSecurityContext()
This is called on the server to unset the security context this is introduced to prevent the re-use of the thread security context on re-use of the thread.

        // logout method from LoginContext not called 
        // as we dont want to unset the appcontainer context

        // First check if this is a local call.
        boolean isLocal = true;
        ServerConnectionContext scc = 
                        SecurityMechanismSelector.getServerConnectionContext();
        if ( scc != null && scc.getSocket() != null )
            isLocal = false;

        if ( !isLocal) 
            com.sun.enterprise.security.SecurityContext.setCurrent(null);