FileDocCategorySizeDatePackage
SecurityContext.javaAPI DocGlassfish v2 API13265Fri May 04 22:35:24 BST 2007com.sun.enterprise.security

SecurityContext

public class SecurityContext extends AbstractSecurityContext
This class that extends AbstractSecurityContext that gets stored in Thread Local Storage. If the current thread creates child threads, the SecurityContext stored in the current thread is automatically propogated to the child threads. This class is used on the server side to represent the security context. Thread Local Storage is a concept introduced in JDK1.2.
see
java.lang.ThreadLocal
see
java.lang.InheritableThreadLocal
author
Harish Prabandham
author
Harpreet Singh

Fields Summary
private static Logger
_logger
private static InheritableThreadLocal
currentSecCtx
private static SecurityContext
defaultSecurityContext
private static AuthPermission
doAsPrivilegedPerm
private boolean
SERVER_GENERATED_SECURITY_CONTEXT
Constructors Summary
public SecurityContext(String userName, Subject subject)



    /* This creates a new SecurityContext object.
     * Note: that the docs for Subject state that the internal sets
     * (eg. the principal set) cannot be modified unless the caller 
     * has the modifyPrincipals AuthPermission. That said, there may
     * be some value to setting the Subject read only.
     * Note: changing the principals in the embedded subject (after
     * construction will likely cause problem in the principal set 
     * keyed HashMaps of EJBSecurityManager.
     * @param username The name of the user/caller principal.
     * @param subject contains the authenticated principals and credential.
     */
         
	Subject s = subject;
	if (s == null) {
	    s = new Subject();
            if (_logger.isLoggable(Level.WARNING)) {
	        _logger.warning("java_security.null_subject");
            }
	} 
	this.initiator = new PrincipalImpl(userName);
        final Subject sub = s;
        this.subject = (Subject)
            AppservAccessController.doPrivileged(new PrivilegedAction(){
                public java.lang.Object run() {
                    sub.getPrincipals().add(initiator);
                    return sub;
                }
            });
    
public SecurityContext(Subject subject)
Create a SecurityContext with given subject having DistinguishedPrincipalCredential. This is used for JMAC environment.

param
subject

        if (subject == null) {
            subject = new Subject();
            if (_logger.isLoggable(Level.WARNING)) {
                _logger.warning("java_security.null_subject");
            }
	} 

        final Subject fsub = subject;
        this.subject = subject;
        this.initiator = (Principal)
            AppservAccessController.doPrivileged(new PrivilegedAction(){
                public java.lang.Object run() {
                    Principal prin = null;
                    Iterator pcIter = fsub.getPublicCredentials().iterator();
                    while (pcIter.hasNext()) {
                        Object obj = pcIter.next();
                        if (obj instanceof DistinguishedPrincipalCredential) {
                            DistinguishedPrincipalCredential dpc =
                                (DistinguishedPrincipalCredential)obj;
                            prin = dpc.getPrincipal();
                            break;
                        }
                    }
                    // for old auth module
                    if (prin == null) {
                        Iterator<Principal> prinIter = fsub.getPrincipals().iterator();
                        if (prinIter.hasNext()) {
                            prin = prinIter.next();
                        }
                    }
                    return prin;
                }
            });

        if (this.initiator == null) {
            this.initiator = getDefaultCallerPrincipal();
        }
    
public SecurityContext(String userName, Subject subject, String realm)

	Subject s = subject;
	if (s == null) {
	    s = new Subject();
            if (_logger.isLoggable(Level.WARNING)) {
	        _logger.warning("java_security.null_subject");
            }
	} 
	this.initiator = PrincipalGroupFactory.getPrincipalInstance(userName, realm);
        final Subject sub = s;
        this.subject = (Subject)
            AppservAccessController.doPrivileged(new PrivilegedAction(){
                public java.lang.Object run() {
                    sub.getPrincipals().add(initiator);
                    return sub;
                }
            });
    
private SecurityContext()

 	this.subject = new Subject();
	// delay assignment of caller principal until it is requested
 	this.initiator = null;
 	this.setServerGeneratedCredentials();
        // read only is only done for guest logins.
 	this.subject.setReadOnly();
    
Methods Summary
public booleandidServerGenerateCredentials()

	return SERVER_GENERATED_SECURITY_CONTEXT;
    
private static com.sun.enterprise.security.SecurityContextgenerateDefaultSecurityContext()

        synchronized (SecurityContext.class) {
	    try{
		return (SecurityContext) 
		    AppservAccessController.doPrivileged(new PrivilegedExceptionAction() {
			    public java.lang.Object run() throws Exception{
				return new SecurityContext();
			    }
			});
	    } catch(Exception e){
		_logger.log(Level.SEVERE,
			    "java_security.security_context_exception",e);
	    }
	}
        return null;
    
public java.security.PrincipalgetCallerPrincipal()
This method returns the caller principal. This information may be redundant since the same information can be inferred by inspecting the Credentials of the caller.

return
The caller Principal.

	return this == defaultSecurityContext ? getDefaultCallerPrincipal() : initiator;
    
public static com.sun.enterprise.security.SecurityContextgetCurrent()
This method gets the SecurityContext stored in the Thread Local Store (TLS) of the current thread.

return
The current Security Context stored in TLS. It returns null if SecurityContext could not be found in the current thread.

	SecurityContext sc = (SecurityContext) currentSecCtx.get();
 	if (sc == null) {
	    sc = defaultSecurityContext;
	}
 	return sc;
    
public static java.security.PrincipalgetDefaultCallerPrincipal()

        synchronized(SecurityContext.class) {
	    if (defaultSecurityContext.initiator == null) { 
		String guestUser = null;
		try {
		    guestUser = (String)
			AppservAccessController.doPrivileged(new PrivilegedExceptionAction() {
				public java.lang.Object run() throws Exception {
				    ConfigContext configContext =
					ApplicationServer.getServerContext().
					getConfigContext();
				    assert(configContext != null);
				    SecurityService securityBean = 
					ServerBeansFactory.
					getSecurityServiceBean(configContext);
				    assert(securityBean != null);
				    return securityBean.getDefaultPrincipal();
				}
			    });
		} catch (Exception e) {
		    _logger.log(Level.SEVERE,
				"java_security.default_user_login_Exception", e);
		} finally {
		    if (guestUser == null) {
			guestUser = "ANONYMOUS";
		    }
		}
		defaultSecurityContext.initiator = new PrincipalImpl(guestUser);
	    }
	}
	return defaultSecurityContext.initiator;
    
public static com.sun.enterprise.security.SecurityContextgetDefaultSecurityContext()

        //unauthen. Security Context.
        return defaultSecurityContext; 
    
public static javax.security.auth.SubjectgetDefaultSubject()

        //Subject of unauthen. Security Context.
        return defaultSecurityContext.subject; 
    
public java.util.SetgetPrincipalSet()

        return subject.getPrincipals();       
    
public javax.security.auth.SubjectgetSubject()

	return subject;
    
public static com.sun.enterprise.security.SecurityContextinit()
Initialize the SecurityContext and handle the unauthenticated principal case

        SecurityContext sc = (SecurityContext) currentSecCtx.get();
        if(sc == null) { // there is no current security context...
            sc = defaultSecurityContext;
	}
        return sc;
    
public static voidreset(com.sun.enterprise.security.SecurityContext sc)
No need to unmarshall the unauthenticated principal....

	setCurrent(sc);
    
public static voidsetCurrent(com.sun.enterprise.security.SecurityContext sc)
This method sets the SecurityContext stored in the TLS.

param
The Security Context that should be stored in TLS. This public static method needs to be protected such that it can only be called by container code. Otherwise it can be called by application code to set its subject (which the EJB security manager will use to create a domain combiner, and then everything the ejb does will be run as the corresponding subject.


 	if (sc != null && sc != defaultSecurityContext) {
 
 	    SecurityContext current = (SecurityContext)currentSecCtx.get();
 
 	    if (sc != current) {
 
 		boolean permitted = false;
 
 		try {
		    SecurityManager sm = System.getSecurityManager();
		    if (sm != null) {
			if(_logger.isLoggable(Level.FINE)){
			    _logger.fine("permission check done to set SecurityContext");
			}
			sm.checkPermission(doAsPrivilegedPerm);
		    }
 		    permitted = true;
 		} catch (java.lang.SecurityException se) {
 		    _logger.log(Level.SEVERE, "java_security.security_context_permission_exception", se);
 		} catch (Throwable t) {
 		    _logger.log(Level.SEVERE, "java_security.security_context_unexpected_exception", t);
 		}
 	    
 		if (permitted) {
		    currentSecCtx.set(sc);
		} else {
 		    _logger.severe("java_security.security_context_nochange");
 		}
 	    }
 	} else {
	    currentSecCtx.set(sc);
	}
    
private voidsetServerGeneratedCredentials()

	SERVER_GENERATED_SECURITY_CONTEXT = true;
    
public static voidsetUnauthenticatedContext()

 	currentSecCtx.set(defaultSecurityContext);
    
public java.lang.StringtoString()

	return "SecurityContext[ " + "Initiator: " + 
	    initiator + "Subject " + subject + " ]";