/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.web.security;
import java.security.*;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.Collections;
import java.lang.*;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import javax.security.jacc.*;
import java.util.logging.*;
import java.util.HashMap;
import java.util.Map;
import com.sun.logging.LogDomains;
import com.sun.web.security.WebPermissionUtil;
import com.sun.enterprise.deployment.WebBundleDescriptor;
import com.sun.enterprise.security.AppservAccessController;
import com.sun.enterprise.security.authorize.*;
import com.sun.enterprise.security.CachedPermission;
import com.sun.enterprise.security.CachedPermissionImpl;
import com.sun.enterprise.security.PermissionCache;
import com.sun.enterprise.security.PermissionCacheFactory;
import com.sun.enterprise.security.SecurityContext;
import com.sun.enterprise.security.audit.AuditManager;
import com.sun.enterprise.security.audit.AuditManagerFactory;
import com.sun.enterprise.security.authorize.PolicyContextHandlerImpl;
import com.sun.enterprise.web.VirtualServer;
import com.sun.enterprise.deployment.runtime.common.SecurityRoleMapping;
import com.sun.enterprise.deployment.PrincipalImpl;
import com.sun.enterprise.deployment.Group;
import com.sun.enterprise.config.serverbeans.*;
import com.sun.enterprise.config.*;
import com.sun.enterprise.server.ApplicationServer;
import com.sun.enterprise.deployment.web.LoginConfiguration;
import com.sun.enterprise.deployment.runtime.web.SunWebApp;
import com.sun.enterprise.deployment.interfaces.SecurityRoleMapperFactory;
import com.sun.enterprise.deployment.interfaces.SecurityRoleMapperFactoryMgr;
import com.sun.enterprise.security.factory.SecurityManagerFactory;
import org.apache.catalina.Globals;
/**
* 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
*/
public class WebSecurityManager extends SecurityManagerFactory {
private static Logger logger =
Logger.getLogger(LogDomains.SECURITY_LOGGER);
private static AuditManager auditManager =
AuditManagerFactory.getAuditManagerInstance();
private static final String RESOURCE = "hasResourcePermission";
private static final String USERDATA = "hasUserDataPermission";
private static final String ROLEREF = "hasRoleRefPermission";
private static final String DEFAULT_PATTERN = "/";
private static final String EMPTY_STRING = "";
private static final PolicyContextHandlerImpl pcHandlerImpl =
(PolicyContextHandlerImpl) PolicyContextHandlerImpl.getInstance();
private static final Map ADMIN_PRINCIPAL = new HashMap();
private static final Map ADMIN_GROUP = new HashMap();
// The context ID associated with this instance. This is the name
// of the application
private String CONTEXT_ID = null;
private String CODEBASE = null;
// The JACC policy provider.
protected Policy policy = Policy.getPolicy();
protected PolicyConfiguration pc = null;
protected static PolicyConfigurationFactory pcf = null;
protected CodeSource codesource = null;
// protection domain cache
private Map protectionDomainCache =
Collections.synchronizedMap(new WeakHashMap());
private static WebResourcePermission allResources =
new WebResourcePermission("/*", (String) null);
private static WebUserDataPermission allConnections =
new WebUserDataPermission("/*", null);
private static Permission[] protoPerms = {
allResources,
allConnections
};
// permissions tied to unchecked permission cache, and used
// to determine if the effective policy is grant all
// WebUserData and WebResource permisions.
private CachedPermission allResourcesCP = null;
private CachedPermission allConnectionsCP = null;
// unchecked permission cache
private PermissionCache uncheckedPermissionCache = null;
private static Set defaultPrincipalSet =
SecurityContext.getDefaultSecurityContext().getPrincipalSet();
private static SecurityRoleMapperFactory factory =
SecurityRoleMapperFactoryMgr.getFactory();
// WebBundledescriptor
private WebBundleDescriptor wbd = null;
// Create a WebSecurityObject
private WebSecurityManager(WebBundleDescriptor wbd) throws PolicyContextException {
this.wbd = wbd;
this.CONTEXT_ID = getContextID(wbd);
String appname = getAppId();
factory.setAppNameForContext(appname, CONTEXT_ID);
initialise(appname);
}
private String removeSpaces(String withSpaces) {
return withSpaces.replace(' ', '_');
}
// fix for CR 6155144
// used to get the policy context id. Also used by the RealmAdapter
public static String getContextID(WebBundleDescriptor wbd) {
String cid = null;
if (wbd != null) {
String moduleId = wbd.getUniqueFriendlyId();
cid = wbd.getApplication().getRegistrationName() +
'/' + wbd.getUniqueFriendlyId();
}
return cid;
}
private void initialise(String appName) throws PolicyContextException {
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);
}
loadPolicyConfiguration();
if (uncheckedPermissionCache == null) {
uncheckedPermissionCache =
PermissionCacheFactory.createPermissionCache(this.CONTEXT_ID, codesource, protoPerms, null);
allResourcesCP =
new CachedPermissionImpl(uncheckedPermissionCache,
allResources);
allConnectionsCP =
new CachedPermissionImpl(uncheckedPermissionCache,
allConnections);
} else {
uncheckedPermissionCache.reset();
}
}
public void loadPolicyConfiguration() throws PolicyContextException {
boolean inService = getPolicyFactory().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) {
pc = getPolicyFactory().getPolicyConfiguration(CONTEXT_ID, false);
try {
WebPermissionUtil.processConstraints(wbd, pc);
WebPermissionUtil.createWebRoleRefPermission(wbd, pc);
} catch (PolicyContextException pce) {
logger.log(Level.FINE, "[Web-Security] FATAL Permission Generation: " + pce.getMessage());
throw pce;
}
}
}
// this will change too - get the application id name
private String getAppId() {
return wbd.getApplication().getRegistrationName();
}
boolean permitAll(HttpServletRequest req) {
boolean ret = false;
WebResourcePermission webResPerm = createWebResourcePermission(req);
if (uncheckedPermissionCache != null) {
ret = uncheckedPermissionCache.checkPermission(webResPerm);
}
if (ret == false) {
ret = checkPermissionWithoutCache(webResPerm, null);
}
return ret;
}
/*
* Invoke the <code>Policy</code> to determine if the <code>Permission</code>
* object has security permission.
* @param perm an instance of <code>Permission</code>.
* @param principalSet a set containing the principals to check for authorization
* @return true if granted, false if denied.
*/
protected boolean checkPermission(Permission perm, Set principalSet) {
boolean ret = false;
if (uncheckedPermissionCache != null) {
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 boolean checkPermissionWithoutCache(
Permission perm, 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);
}
// obtains PolicyConfigurationFactory once for class
private static synchronized PolicyConfigurationFactory getPolicyFactory()
throws PolicyContextException {
if (pcf == null) {
try {
pcf = PolicyConfigurationFactory.getPolicyConfigurationFactory();
} catch (ClassNotFoundException cnfe) {
logger.severe("jaccfactory.notfound");
throw new PolicyContextException(cnfe);
} catch (PolicyContextException pce) {
logger.severe("jaccfactory.notfound");
throw pce;
}
}
return pcf;
}
private WebResourcePermission createWebResourcePermission(
HttpServletRequest httpsr) {
String uri = (String) httpsr.getAttribute(Globals.CONSTRAINT_URI);
if (uri == null) {
uri = httpsr.getRequestURI();
if (uri != null) {
// FIX TO BE CONFIRMED: subtract the context path
String contextPath = httpsr.getContextPath();
int contextLength = contextPath == null ? 0 :
contextPath.length();
if (contextLength > 0) {
uri = uri.substring(contextLength);
}
}
}
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;
} else {
// FIX TO BE CONFIRMED: encode all colons
uri = uri.replaceAll(":","%3A");
}
WebResourcePermission perm = new WebResourcePermission(
uri, httpsr.getMethod());
return perm;
}
/**
* Perform access control based on the <code>HttpServletRequest</code>.
* Return <code>true</code> if this constraint is satisfied and processing
* should continue, or <code>false</code> otherwise.
* @return true is the resource is granted, false if denied
*/
public boolean hasResourcePermission(HttpServletRequest httpsr) {
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;
}
/*
* Return <code>true</code> if the specified servletName has the specified
* security role, within the context of the WebRoleRefPermission;
* otherwise return
* <code>false</code>.
*
* @param principal servletName the resource's name.
* @param principal Principal for whom the role is to be checked
* @param role Security role to be checked
* @return true is the resource is granted, false if denied
*/
public boolean hasRoleRefPermission(String servletName, String role, 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;
}
/*
* Enforce any user data constraint required by the security constraint
* guarding this request URI. Return <code>true</code> if this constraint
* was not violated and processing should continue, or <code>false</code>
* if we have created a response already.
*
* @return true is the user is granted, false if denied.
*/
public int hasUserDataPermission(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;
}
public void destroy() throws PolicyContextException {
boolean wasInService = getPolicyFactory().inService(CONTEXT_ID);
getPolicyFactory().getPolicyConfiguration(CONTEXT_ID, true);
if (wasInService) {
policy.refresh();
PermissionCacheFactory.removePermissionCache(uncheckedPermissionCache);
uncheckedPermissionCache = null;
}
factory.removeAppNameForContext(CONTEXT_ID);
WebSecurityManager wsm = WebSecurityManager.getManager(CONTEXT_ID, null, true);
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "WebSecurityManager: destroyed" + wsm);
}
}
private static String setPolicyContext(final String ctxID) throws Throwable {
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;
}
/**
* This is an private method for transforming principal into a SecurityContext
* @param principal expected to be a WebPrincipal
* @return SecurityContext
*/
private SecurityContext getSecurityContext(Principal principal) {
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;
}
/**
* This is an private method for policy context handler data info
* @param httpRequest
*/
private void setSecurityInfo(HttpServletRequest httpRequest) {
if (httpRequest != null) {
pcHandlerImpl.getHandlerData().setHttpServletRequest(httpRequest);
}
}
private String principalSetToString(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 String getVirtualServers(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 static Principal getAdminPrincipal(String username, String realmName) {
return (Principal) ADMIN_PRINCIPAL.get(realmName + username);
}
public static Principal getAdminGroup(String group, String realmName) {
return (Principal) ADMIN_GROUP.get(realmName + group);
}
/**
* returns true to indicate that a policy check was made
* and there were no constrained resources.
* when caching is disabled must always return false, which will
* ensure that policy is consulted to authorize each request.
*/
public boolean hasNoConstrainedResources() {
if (allResourcesCP != null && allConnectionsCP != null) {
boolean x = allResourcesCP.checkPermission();
boolean y = allConnectionsCP.checkPermission();
return x && y;
}
return false;
}
// stores the context ids to appnames for standalone web apps
static private Map<String, ArrayList<String>> CONTEXT_IDS =
new HashMap<String, ArrayList<String>>();
static private Map<String, Map<String, WebSecurityManager>> SECURITY_MANAGERS =
new HashMap<String, Map<String, WebSecurityManager>>();
public static <T> WebSecurityManager getManager(String ctxId, String name,
boolean remove) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "getManager before printcache" + remove);
printCache();
}
WebSecurityManager wsm = getManager(SECURITY_MANAGERS, ctxId, name, remove);
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "getManager after printcache" + remove);
printCache();
}
return wsm;
}
public static <T> ArrayList<WebSecurityManager> getManagers(String ctxId, boolean remove) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "getManagers before printcache" + remove);
printCache();
}
ArrayList<WebSecurityManager> wslist = getManagers(SECURITY_MANAGERS, ctxId, remove);
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "getManagers after printcache" + remove);
printCache();
}
return wslist;
}
public static <T> ArrayList<WebSecurityManager> getManagersForApp(String appName, boolean remove) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "getManagersForApp before printcache" + remove);
printCache();
}
ArrayList<WebSecurityManager> wslist = getManagersForApp(SECURITY_MANAGERS, CONTEXT_IDS, appName,
remove);
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "getManagersForApp after printcache" + remove);
printCache();
}
return wslist;
}
public static <T> String[] getContextsForApp(String appName, boolean remove) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "getContextsForApp before printcache" + remove);
}
printCache();
String[] ctxList = getContextsForApp(CONTEXT_IDS, appName, remove);
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "getContextsForApp after printcache" + remove);
printCache();
}
return ctxList;
}
public static <T> void addManagerToApp(String ctxId, String name,
String appName, WebSecurityManager manager) {
addManagerToApp(SECURITY_MANAGERS, CONTEXT_IDS, ctxId, name,
appName, manager);
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "addManagerToApp before printcache" + manager);
printCache();
}
}
public static WebSecurityManager createManager(WebBundleDescriptor wbd,
boolean register) {
String ctxId = WebSecurityManager.getContextID(wbd);
WebSecurityManager manager = null;
if (register) {
manager = getManager(ctxId, null, false);
}
if (manager == null || !register) {
try {
manager = new WebSecurityManager(wbd);
if (register) {
String appName = wbd.getApplication().getRegistrationName();
addManagerToApp(ctxId, null, appName, manager);
}
} catch (javax.security.jacc.PolicyContextException e) {
logger.log(Level.FINE, "[Web-Security] FATAL Exception. Unable to create WebSecurityManager: " + e.getMessage());
throw new RuntimeException(e);
}
}
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "WebSecurityManager called with" + register);
logger.log(Level.FINE, "WebSecurityManager " + manager + "returned");
}
return manager;
}
static void printCache() {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "CONTEXT_IDS :" + CONTEXT_IDS.toString());
logger.log(Level.FINE, "SECURITY_MANAGERS :" + SECURITY_MANAGERS.toString());
}
}
}