FileDocCategorySizeDatePackage
WebSecurityManager.javaAPI DocGlassfish v2 API24638Mon Jun 18 16:14:54 BST 2007com.sun.web.security

WebSecurityManager

public class WebSecurityManager extends Object
The class implements the JSR 115 - JavaTM Authorization Contract for Containers. This class is a companion class of EJBSecurityManager. All the security decisions required to allow access to a resource are defined in that class.
author
Jean-Francois Arcand
author
Harpreet Singh.
todo
introduce a new class called AbstractSecurityManager. Move functionality from this class and EJBSecurityManager class and extend this class from AbstractSecurityManager

Fields Summary
private static Logger
logger
private static com.sun.enterprise.security.audit.AuditManager
auditManager
private static final String
RESOURCE
private static final String
USERDATA
private static final String
ROLEREF
private static final String
DEFAULT_PATTERN
private static final String
EMPTY_STRING
private static final com.sun.enterprise.security.authorize.PolicyContextHandlerImpl
pcHandlerImpl
private static final Map
ADMIN_PRINCIPAL
private static final Map
ADMIN_GROUP
private String
CONTEXT_ID
private String
CODEBASE
protected Policy
policy
protected PolicyConfiguration
policyConfiguration
protected PolicyConfigurationFactory
policyConfigurationFactory
protected CodeSource
codesource
private Map
protectionDomainCache
private static WebResourcePermission
allResources
private static WebUserDataPermission
allConnections
private static Permission[]
protoPerms
private com.sun.enterprise.security.CachedPermission
allResourcesCP
private com.sun.enterprise.security.CachedPermission
allConnectionsCP
private com.sun.enterprise.security.PermissionCache
uncheckedPermissionCache
private static Set
defaultPrincipalSet
private static com.sun.enterprise.deployment.interfaces.SecurityRoleMapperFactory
factory
private com.sun.enterprise.deployment.WebBundleDescriptor
wbd
Constructors Summary
public WebSecurityManager(com.sun.enterprise.deployment.WebBundleDescriptor wbd)

    // Create a WebSecurityObject
         
        this.wbd = wbd;
        this.CONTEXT_ID = getContextID(wbd);
        String appname = getAppId();
        factory.setAppNameForContext(appname, CONTEXT_ID);
        initialise();
    
Methods Summary
protected booleancheckPermission(java.security.Permission perm, java.util.Set principalSet)

   
        boolean ret = uncheckedPermissionCache.checkPermission(perm);
        if (ret == false) {
            ret = checkPermissionWithoutCache(perm, principalSet);
        } else {
            try {
                setPolicyContext(CONTEXT_ID);
            } catch(Throwable t){
                if (logger.isLoggable(Level.FINE)){
 	            logger.log(Level.FINE, 
                        "[Web-Security] Web Permission Access Denied.",t);
                }
 	        ret = false;
            }
        }
        return ret;
    
private booleancheckPermissionWithoutCache(java.security.Permission perm, java.util.Set principalSet)

         
        try{
 
 	    // NOTE: there is an assumption here, that this setting of the PC will
 	    // remain in affect through the component dispatch, and that the
 	    // component will not call into any other policy contexts.
	    // even so, could likely reset on failed check.
 	    
 	    setPolicyContext(CONTEXT_ID);
 
 	} catch(Throwable t){
            if (logger.isLoggable(Level.FINE)){
 	        logger.log(Level.FINE, 
                    "[Web-Security] Web Permission Access Denied.",t);
            }
 	    return false;
 	}
 
	ProtectionDomain prdm = 
		(ProtectionDomain)protectionDomainCache.get(principalSet);
  
	if (prdm == null) {

            Principal[] principals = null;
            principals = (principalSet == null ? null : 
                      (Principal []) principalSet.toArray(new Principal[0]));

            if(logger.isLoggable(Level.FINE)){
                logger.log(Level.FINE,"[Web-Security] Generating a protection domain for Permission check.");

                if (principals != null) {
                    for (int i=0; i<principals.length; i++){
                        logger.log(Level.FINE, "[Web-Security] Checking with Principal : "+ principals[i].toString());
                    }
                } else {
                    logger.log(Level.FINE, "[Web-Security] Checking with Principals: null");
                }
            }

            prdm = new ProtectionDomain(codesource, null, null,principals);
            protectionDomainCache.put(principalSet,prdm);
        }

        if(logger.isLoggable(Level.FINE)){
            logger.log(Level.FINE, "[Web-Security] Codesource with Web URL: " + codesource.getLocation().toString());
            logger.log(Level.FINE, "[Web-Security] Checking Web Permission with Principals : "+ principalSetToString(principalSet));
            logger.log(Level.FINE, "[Web-Security] Web Permission = " +perm.toString());
        }
  
        return policy.implies(prdm, perm);
    
private WebResourcePermissioncreateWebResourcePermission(javax.servlet.http.HttpServletRequest httpsr)

        String uri = (String)httpsr.getAttribute(Globals.CONSTRAINT_URI);
        if (uri == null) {
            uri = httpsr.getRequestURI();
        }
        if (uri == null) {
            if (logger.isLoggable(Level.FINE)){
                logger.log(Level.FINE,"[Web-Security] mappedUri is null");
            }
            throw new RuntimeException("Fatal Error in creating WebResourcePermission");
        }
        if(uri.equals("/")) {
            uri = EMPTY_STRING;
        }
        WebResourcePermission perm = new WebResourcePermission(
                uri, httpsr.getMethod());
        return perm;
    
public voiddestroy()

        boolean wasInService = getFactory().inService(CONTEXT_ID);
	if (policyConfiguration == null) {
	    policyConfiguration = getFactory().
		getPolicyConfiguration(CONTEXT_ID,false);
	}
        if (wasInService) {
            policy.refresh();
            PermissionCacheFactory.removePermissionCache
		(uncheckedPermissionCache);
            uncheckedPermissionCache = null;
        }
        factory.removeAppNameForContext(CONTEXT_ID);
        // pc.delete() will be invoked during undeployment
	//policyConfiguration.delete();
        WebSecurityManagerFactory.getInstance().removeWebSecurityManager(CONTEXT_ID);
    
private voidgeneratePermissions()

        try{
            WebPermissionUtil.processConstraints(wbd, policyConfiguration);    
            WebPermissionUtil.createWebRoleRefPermission(wbd, policyConfiguration); 
        } catch (PolicyContextException pce){
            logger.log(Level.FINE,"[Web-Security] FATAL Permission Generation: " + pce.getMessage());
            throw new RuntimeException("Fatal error creating web permissions", pce);
        }
    
public static java.security.PrincipalgetAdminGroup(java.lang.String group, java.lang.String realmName)

        return (Principal)ADMIN_GROUP.get(realmName+group);
    
public static java.security.PrincipalgetAdminPrincipal(java.lang.String username, java.lang.String realmName)

        return (Principal)ADMIN_PRINCIPAL.get(realmName+username);
    
private java.lang.StringgetAppId()

        return wbd.getApplication().getRegistrationName();
    
public static java.lang.StringgetContextID(com.sun.enterprise.deployment.WebBundleDescriptor wbd)

        String cid = null;
        if (wbd != null ) {
            String moduleId = wbd.getUniqueFriendlyId();
            cid = wbd.getApplication().getRegistrationName() +
                '/" + wbd.getUniqueFriendlyId();
        }
        return cid;
   
protected PolicyConfigurationFactorygetFactory()

        if (policyConfigurationFactory == null){
            try{
                policyConfigurationFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
            } catch(java.lang.ClassNotFoundException ex){
                // FIX ME: Need to create an approriate exception
                throw new PolicyContextException(ex);
            } 
        }
        return policyConfigurationFactory;
    
private com.sun.enterprise.security.SecurityContextgetSecurityContext(java.security.Principal principal)
This is an private method for transforming principal into a SecurityContext

param
principal expected to be a WebPrincipal
return
SecurityContext

        SecurityContext secContext = null;
        if (principal != null) {
	    if (principal instanceof WebPrincipal){
		WebPrincipal wp = (WebPrincipal)principal;
		secContext = wp.getSecurityContext();
	    }else {
		secContext = new SecurityContext(principal.getName(),null);
	    }
        } 
	if (secContext == null) {
            secContext = SecurityContext.getDefaultSecurityContext();
        }
	return secContext;
    
private java.lang.StringgetVirtualServers(java.lang.String appName)

        String ret = null;
        try {
            ConfigContext ctx =
                ApplicationServer.getServerContext().getConfigContext();
            ret = ServerBeansFactory
                    .getVirtualServersByAppName(ctx, appName);
        } catch (ConfigException ce) {
            logger.log(Level.FINE, "Cannot get virtual server for " + appName, ce);
        }
        return ret;
    
public booleanhasNoConstrainedResources()

	if (allResourcesCP != null && allConnectionsCP != null) {
	    boolean x = allResourcesCP.checkPermission();
	    boolean y = allConnectionsCP.checkPermission();
	    return x && y;
        }
	return false;
    
public booleanhasResourcePermission(javax.servlet.http.HttpServletRequest httpsr)
Perform access control based on the HttpServletRequest. Return true if this constraint is satisfied and processing should continue, or false otherwise.

return
true is the resource is granted, false if denied

	SecurityContext sc = getSecurityContext(httpsr.getUserPrincipal());
        WebResourcePermission perm = createWebResourcePermission(httpsr);
        setSecurityInfo(httpsr);
        boolean isGranted = checkPermission(perm,sc.getPrincipalSet());
	SecurityContext.setCurrent(sc);
        if(logger.isLoggable(Level.FINE)){
            logger.log(Level.FINE,"[Web-Security] hasResource isGranted: " + isGranted);
            logger.log(Level.FINE,"[Web-Security] hasResource perm: " + perm);
        }
        if(auditManager.isAuditOn()){
            Principal prin = httpsr.getUserPrincipal();
            String user = (prin != null) ? prin.getName(): null;
            auditManager.webInvocation(user, httpsr, RESOURCE, isGranted);
        }
        return isGranted;
    
public booleanhasRoleRefPermission(java.lang.String servletName, java.lang.String role, java.security.Principal p)

	Set principalSet = getSecurityContext(p).getPrincipalSet();
        WebRoleRefPermission perm = new WebRoleRefPermission(servletName, role);
        boolean isGranted = checkPermission(perm,principalSet);
        if(logger.isLoggable(Level.FINE)){
            logger.log(Level.FINE,"[Web-Security] hasRoleRef perm: " + perm);
            logger.log(Level.FINE,"[Web-Security] hasRoleRef isGranted: " + isGranted);
        }
        return isGranted;
    
public inthasUserDataPermission(javax.servlet.http.HttpServletRequest httpsr)

        setSecurityInfo(httpsr);
        WebUserDataPermission perm = new WebUserDataPermission(httpsr);       
        boolean  isGranted = checkPermission(perm, defaultPrincipalSet);
        int result = 0;
       
        if ( isGranted ) {
            result = 1;
        }
 
        if(logger.isLoggable(Level.FINE)){
            logger.log(Level.FINE,"[Web-Security] hasUserDataPermission perm: " + perm);
            logger.log(Level.FINE,"[Web-Security] hasUserDataPermission isGranted: " + isGranted);
        }

        if(auditManager.isAuditOn()){
            Principal prin = httpsr.getUserPrincipal();
            String user = (prin != null) ? prin.getName(): null;
            auditManager.webInvocation(user, httpsr, USERDATA, isGranted);
        }

        if ( !isGranted ) {

             perm = new WebUserDataPermission
		 ( perm.getName(),
		   new String[] { httpsr.getMethod() },
		   "CONFIDENTIAL" );

             isGranted = checkPermission(perm, defaultPrincipalSet);

             if (isGranted)
                result = -1;
        }
        
        return result;
    
private voidinitialise()

       String appName = wbd.getApplication().getRegistrationName();
        CODEBASE = removeSpaces(CONTEXT_ID) ;
        if(VirtualServer.ADMIN_VS.equals(getVirtualServers(appName))){
            LoginConfiguration lgConf = wbd.getLoginConfiguration();
            if (lgConf != null){
                String realmName = lgConf.getRealmName();
                SunWebApp sunDes = wbd.getSunDescriptor();
                if(sunDes != null){
                    SecurityRoleMapping[] sr = sunDes.getSecurityRoleMapping();
                    if(sr != null){
                        for(int i=0; i<sr.length; i++){
                            String[] principal = sr[i].getPrincipalName();
                            if(principal != null){
                                for(int plen=0;plen<principal.length; plen++ ){
                                    ADMIN_PRINCIPAL.put(realmName+principal[plen], new PrincipalImpl(principal[plen]));
                                }
                            }
                            List<String> groups = sr[i].getGroupNames();
                            for(int glen = 0; glen < groups.size(); glen++ ){
                                ADMIN_GROUP.put(realmName+groups.get(glen), new Group(groups.get(glen))) ;
                            }
                        }
                    }
                }
            }
        }
 
        // will require stuff in hash format for reference later on.
        try{
            java.net.URI uri = null;
            try{
		if(logger.isLoggable(Level.FINE))
		    logger.log(Level.FINE, "[Web-Security] Creating a Codebase URI with = "+CODEBASE);
		uri = new java.net.URI("file:///"+ CODEBASE);
		if(uri != null){
		    codesource = new CodeSource(new URL(uri.toString()), 
                            (java.security.cert.Certificate[]) null);
		}
		
            } catch(java.net.URISyntaxException use){
                // manually create the URL
                logger.log(Level.FINE, "[Web-Security] Error Creating URI ", use);
                throw new RuntimeException(use);
            }

        } catch(java.net.MalformedURLException mue){
            logger.log(Level.SEVERE, "ejbsm.codesourceerror", mue);
            throw new RuntimeException(mue);
        } 

        if(logger.isLoggable(Level.FINE)){
            logger.fine("[Web-Security] Context id (id under which  WEB component in application will be created) = "+ CONTEXT_ID);
            logger.fine("[Web-Security] Codebase (module id for web component) "+ CODEBASE);
        }

 	boolean inService = getFactory().inService(CONTEXT_ID);

 	// only regenerate policy file if it isn't already in service
 	// Consequently all things that deploy modules (as apposed to
 	// loading already deployed modules) must make sure pre-exiting
 	// pc is either in deleted or open state before this method
 	// (i.e. initialise) is called. That is, before constructing
 	// the WebSecurityManager. Note that policy statements are not
 	// removed to allow multiple web modules to be represented by same pc.
 
 	if (!inService) {
 	    policyConfiguration = getFactory().getPolicyConfiguration(CONTEXT_ID,false);
  	    generatePermissions();
  	}
 
 	if (uncheckedPermissionCache == null) {
 	    uncheckedPermissionCache =
		PermissionCacheFactory.createPermissionCache
		(this.CONTEXT_ID, codesource, protoPerms, null);

	    if (uncheckedPermissionCache != null) {
 
		allResourcesCP = 
		    new CachedPermissionImpl(uncheckedPermissionCache,
					     allResources);
		allConnectionsCP = 
		    new CachedPermissionImpl(uncheckedPermissionCache,
					     allConnections);
	    }

 	} else {
 	    uncheckedPermissionCache.reset();
 	}
 
    
booleanpermitAll(javax.servlet.http.HttpServletRequest req)

        WebResourcePermission webResPerm = new WebResourcePermission(req);
        boolean ret = uncheckedPermissionCache.checkPermission(webResPerm);
        if (ret == false) {
            ret = checkPermissionWithoutCache(webResPerm, null);
        } 
        return ret;
    
private java.lang.StringprincipalSetToString(java.util.Set principalSet)

 	String result = null;
 	if (principalSet != null) {
 	    Principal[] principals = 
 		(Principal []) principalSet.toArray(new Principal[0]);
 	    for (int i =0; i<principals.length; i++) {
 		if (i == 0) {
 		    result = principals[i].toString();
 		} else {
 		    result = result + ", "+ new String(principals[i].toString());
 		}
 	    }
 	}
 	return result;
    
private java.lang.StringremoveSpaces(java.lang.String withSpaces)

        return withSpaces.replace(' ", '_");
    
private static java.lang.StringsetPolicyContext(java.lang.String ctxID)

	String old = PolicyContext.getContextID();
	if (old != ctxID && 
	    (old == null || ctxID == null || !old.equals(ctxID))) {
  
	    if(logger.isLoggable(Level.FINE)){
		logger.fine("[Web-Security] Setting Policy Context ID: old = " + old + 
			    " ctxID = " + ctxID);
	    }
  
	    try {  
		AppservAccessController.doPrivileged(new PrivilegedExceptionAction(){
		    public java.lang.Object run() throws Exception{
			PolicyContext.setContextID(ctxID);
			return null;
		    }
		});
	    } catch (java.security.PrivilegedActionException pae) {
		Throwable cause = pae.getCause();
		if( cause instanceof java.security.AccessControlException) {
		    logger.log(Level.SEVERE,"[Web-Security] setPolicy SecurityPermission required to call PolicyContext.setContextID",cause);
		} else {
		    logger.log(Level.SEVERE,"[Web-Security] Unexpected Exception while setting policy context",cause);
		}
		throw cause;
	    }
	} else if(logger.isLoggable(Level.FINE)){
	    logger.fine("[Web-Security] Policy Context ID was: " + old);
	}
	return old;
    
private voidsetSecurityInfo(javax.servlet.http.HttpServletRequest httpRequest)
This is an private method for policy context handler data info

param
httpRequest

        if (httpRequest != null) {
            pcHandlerImpl.getHandlerData().setHttpServletRequest(httpRequest);
        }