FileDocCategorySizeDatePackage
RealmAdapter.javaAPI DocGlassfish v2 API55127Fri May 04 22:36:20 BST 2007com.sun.web.security

RealmAdapter

public class RealmAdapter extends org.apache.catalina.realm.RealmBase
This is the realm adapter used to authenticate users and authorize access to web resources. The authenticate method is called by Tomcat to authenticate users. The hasRole method is called by Tomcat during the authorization process.
author
Harpreet Singh
author
JeanFrancois Arcand

Fields Summary
private static final String
UNCONSTRAINED
private static final Logger
_logger
public static final String
SECURITY_CONTEXT
public static final String
BASIC
public static final String
FORM
private static final String
SERVER_AUTH_CONTEXT
private static final String
MESSAGE_INFO
private static final String
SYSTEM_HTTPSERVLET_SECURITY_PROVIDER
private com.sun.enterprise.deployment.interfaces.SecurityRoleMapper
mapper
private com.sun.enterprise.deployment.WebBundleDescriptor
webDesc
private HashMap
runAsPrincipals
private String
_realmName
protected static final String
name
Descriptive information about this Realm implementation.
private String
CONTEXT_ID
The context Id value needed by the jacc architecture.
private org.apache.catalina.Container
virtualServer
protected static final org.apache.catalina.util.StringManager
sm
The string manager for this package.
protected static final org.apache.catalina.util.StringManager
smRA
protected volatile WebSecurityManager
webSecurityManager
A WebSecurityManager object associated with a CONTEXT_ID
protected WebSecurityManagerFactory
webSecurityManagerFactory
The factory used for creating WebSecurityManager object.
protected boolean
isCurrentURIincluded
private ArrayList
roles
protected final ReadWriteLock
rwLock
private boolean
contextEvaluated
private String
loginPage
private String
errorPage
private static org.apache.catalina.deploy.SecurityConstraint[]
emptyConstraints
private static String
defaultSystemProviderID
the default provider id for system apps if one has been established. the default provider for system apps is established by defining a system property.
private String
appID
private boolean
isSystemApp
private String
jmacProviderRegisID
private com.sun.enterprise.security.jmac.config.HttpServletHelper
helper
private static String
PROXY_AUTH_TYPE
Constructors Summary
public RealmAdapter()


      
public RealmAdapter(String realmName)
Create for WS Ejb endpoint authentication. Roles related data is not available here.

        _realmName = realmName;
    
public RealmAdapter(com.sun.enterprise.deployment.WebBundleDescriptor descriptor, boolean isSystemApp)
Create the realm adapter. Extracts the role to user/group mapping from the runtime deployment descriptor.

param
the web bundle deployment descriptor.
param
isSystemApp if the app is a system app.

        this(descriptor, isSystemApp, null);
    
public RealmAdapter(com.sun.enterprise.deployment.WebBundleDescriptor descriptor, boolean isSystemApp, String realmName)
Create the realm adapter. Extracts the role to user/group mapping from the runtime deployment descriptor.

param
the web bundle deployment descriptor.
param
isSystemApp if the app is a system app.
param
realmName The realm name to use if the app does not specify its own


        this.isSystemApp = isSystemApp;
        webDesc = descriptor;
        Application app = descriptor.getApplication();
        mapper = app.getRoleMapper();
        LoginConfiguration loginConfig = descriptor.getLoginConfiguration();
        _realmName = app.getRealm();
        if (_realmName == null && loginConfig != null) {
            _realmName = loginConfig.getRealmName();
        }
        if (realmName != null
                && (_realmName == null || _realmName.equals(""))) {
            _realmName = realmName;
        }

        // BEGIN IASRI 4747594
   	CONTEXT_ID = WebSecurityManager.getContextID(descriptor);
        runAsPrincipals = new HashMap();
        Iterator bundle = webDesc.getWebComponentDescriptorsSet().iterator();
	
        while(bundle.hasNext()) {
            
            WebComponentDescriptor wcd = (WebComponentDescriptor)bundle.next();
            RunAsIdentityDescriptor runAsDescriptor = wcd.getRunAsIdentity();
	    
            if (runAsDescriptor != null) {
                String principal = runAsDescriptor.getPrincipal();
                String servlet = wcd.getCanonicalName();
		
                if (principal == null || servlet == null) {
                    _logger.warning("web.realmadapter.norunas");
                } else {
                    runAsPrincipals.put(servlet, principal);
                    _logger.fine("Servlet "+servlet+
                     " will run-as: "+principal);
		}
	    }
	}	
	// END IASRI 4747594

	this.appID = app.getRegistrationName();
        // helper are set until setVirtualServer is invoked
    
Methods Summary
public java.security.Principalauthenticate(java.lang.String username, byte[] authData)
Authenticates and sets the SecurityContext in the TLS.

return
the authenticated principal.
param
the user name.
param
the authenticated data.

        return authenticate(username, new String(authData));
    
public java.security.Principalauthenticate(java.lang.String username, java.lang.String password)
Authenticates and sets the SecurityContext in the TLS.

return
the authenticated principal.
param
the user name.
param
the password.

        if (_logger.isLoggable(Level.FINE)){
            _logger.fine( "Tomcat callback for authenticate user/password");
            _logger.fine( "usename = " + username);
        }
        if(authenticate(username, password, null)) {
            SecurityContext secCtx = SecurityContext.getCurrent();
            assert (secCtx != null); // or auth should've failed
            return new WebPrincipal(username, password, secCtx);
        } else {
            return null;
        }
    
public java.security.Principalauthenticate(java.security.cert.X509Certificate[] certs)

        if(authenticate(null, null, certs)) {
            SecurityContext secCtx = SecurityContext.getCurrent();
            assert (secCtx != null); // or auth should've failed
            return new WebPrincipal(certs, secCtx);
        } else {
            return null;
        }
    
public booleanauthenticate(WebPrincipal prin)

        if (prin.isUsingCertificate()) {
            return authenticate(null, null, prin.getCertificates());
        } else {
            return authenticate(prin.getName(), prin.getPassword(), null);
        }
    
protected booleanauthenticate(java.lang.String username, java.lang.String password, java.security.cert.X509Certificate[] certs)
Authenticates and sets the SecurityContext in the TLS.

return
true if authentication succeeded, false otherwise.
param
the username.
param
the authentication method.
param
the authentication data.


        SecurityContext.setCurrent(null);
        String realm_name = null;
        boolean success = false;
        try {
            if (certs != null) {
                Subject subject = new Subject();
                X509Certificate certificate = certs[0];
                X500Name x500Name = (X500Name) certificate.getSubjectDN();
                Switch.getSwitch().getCallFlowAgent().addRequestInfo(
                        RequestInfo.REMOTE_USER, x500Name.getName());
                subject.getPublicCredentials().add(x500Name);
                LoginContextDriver.login(subject, X500Name.class);
                realm_name = CertificateRealm.AUTH_TYPE;
            } else {
                Switch.getSwitch().getCallFlowAgent().addRequestInfo(
                        RequestInfo.REMOTE_USER, username);
                realm_name = _realmName;
                LoginContextDriver.login(username, password, realm_name);
            }
            success = true;
        } catch (Exception le) {
            success = false;
            if (_logger.isLoggable(Level.WARNING)) {
                _logger.warning("Web login failed: " + le.getMessage());
            }
        }
        if(success){
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE,"Web login succeeded for: " + username);
            }
        }
        if (webDesc!=null && webDesc.hasWebServices()) {
            WebPrincipal principal = new WebPrincipal(username, password, null);
            for (AuthenticationListener listener : WebServiceEngineImpl.getInstance().getAuthListeners()) {
                if (success) {
                    listener.authSucess(webDesc, null, principal);                        
                } else {
                    listener.authFailure(webDesc, null, principal);
                }
            }
        }
        return success;
    
public java.security.PrincipalcreateFailOveredPrincipal(java.lang.String username)
This method is added to create a Principal based on the username only. Hercules stores the username as part of authentication failover and needs to create a Principal based on username only

param
username
return
Principal for the user username HERCULES:add

        _logger.log(Level.FINEST,"IN createFailOveredPrincipal ("+username+")");
        //set the appropriate security context
        loginForRunAs(username);
        SecurityContext secCtx = SecurityContext.getCurrent();
         _logger.log(Level.FINE,"Security context is "+secCtx);
        assert (secCtx != null);
        Principal principal = new WebPrincipal(username, null, secCtx);
        _logger.log(Level.INFO,"Principal created for FailOvered user "+principal);
        return principal;
    
public voiddestroy()

        super.destroy();
        if (helper != null) {
            helper.disable();
        }
    
public org.apache.catalina.deploy.SecurityConstraint[]findSecurityConstraints(org.apache.catalina.HttpRequest request, org.apache.catalina.Context context)
Returns null 1. if there are no security constrainst defined on any of the web resources within the context, or 2. if the target is a form login related page or target. otherwise return an empty array of SecurityConstraint.

	WebSecurityManager secMgr = getWebSecurityManager(false);
 
	if (secMgr != null && secMgr.hasNoConstrainedResources()) {
	    return null;
	}
 
	SecurityConstraint[] constraints = RealmAdapter.emptyConstraints;
	return constraints;
    
private java.lang.StringgetAppContextID()
This must be invoked after virtualServer is set.

        return this.virtualServer.getName() + " " + webDesc.getContextRoot();
    
private java.lang.StringgetCanonicalName(javax.servlet.http.HttpServletRequest currentRequest)

    //END SJSAS 6232464
        String servletUri = "";
        String currentUri = "";
        String aliasUri = "";
        String currentUriExtension = "";
        String aliasUriExtension = "";        
        boolean isAliasExists = false;
        for (Iterator itr = webDesc.getWebComponentDescriptorsSet().iterator(); itr.hasNext();) {
            WebComponentDescriptor webComponentDescriptor = (WebComponentDescriptor)itr.next();
            servletUri = webComponentDescriptor.getWebComponentImplementation();

            currentUri = getResourceName( currentRequest.getRequestURI(), currentRequest.getContextPath());
            currentUriExtension = getExtension(currentUri);
            
            // First check the servlet mapping
            for (Iterator i = webComponentDescriptor.getUrlPatternsSet().iterator(); i.hasNext();) {
                aliasUri = i.next().toString();
                aliasUriExtension = getExtension(aliasUri);
                
                if (aliasUri.equalsIgnoreCase(currentUri)){
                    isAliasExists = true;
                    break;
                }     
                
                if (aliasUriExtension.equalsIgnoreCase(currentUriExtension) 
                        && aliasUri.equalsIgnoreCase("*" + aliasUriExtension)){
                    isAliasExists = true;
                    break;
                }  
            }

            if (currentUri.equalsIgnoreCase(servletUri) 
                    || isAliasExists){
                return webComponentDescriptor.getCanonicalName();
            }            
        }
        return UNCONSTRAINED;
    
private com.sun.enterprise.security.jmac.config.HttpServletHelpergetConfigHelper()
This must be invoked after virtualServer is set.

        Map map = new HashMap();
        map.put(HttpServletConstants.WEB_BUNDLE, webDesc);
        return new HttpServletHelper(getAppContextID(),
            map, null, // null handler
            _realmName, isSystemApp, defaultSystemProviderID);
    
private static java.lang.StringgetDefaultSystemProviderID()
get the default provider id for system apps if one has been established. the default provider for system apps is established by defining a system property.

return
the provider id or null.

	String p = System.getProperty(SYSTEM_HTTPSERVLET_SECURITY_PROVIDER);
	if (p != null) {
	    p = p.trim();
	    if (p.length() == 0) {
		p = null;
	    }
	}
	return p;
    
private java.lang.StringgetExtension(java.lang.String uri)

        try{
            return uri.substring(uri.lastIndexOf("."));           
        } catch (java.lang.Exception ex){
            // don't use the cache and let jacc create the permission.
            return "";
        }   
    
protected java.lang.StringgetName()
Return a short name for this Realm Adapter implementation.

        return (this.name);
    
protected java.lang.StringgetPassword(java.lang.String username)

        throw new IllegalStateException("Should not reach here");
    
protected java.security.PrincipalgetPrincipal(java.lang.String username)

        throw new IllegalStateException("Should not reach here");
    
public java.lang.StringgetRealmName()
Return the name of the realm this RealmAdapter uses.

return
realm name

         return _realmName;
     
private java.lang.StringgetResourceName(java.lang.String uri, java.lang.String contextPath)

        try{
            return uri.substring(contextPath.length());           
        } catch (java.lang.Exception ex){
            return "";
        }   
    
private com.sun.enterprise.security.SecurityContextgetSecurityContext()

        return SecurityContext.getCurrent ();
    
private java.lang.StringgetServletName(com.sun.enterprise.ComponentInvocation inv)
Obtain servlet name from invocation.

In order to obtain the servlet name the following must be true: The ComponentInvocation contains a 'class' of type HttpServlet, which contains a valid ServletConfig object. This method returns the value returned by getServletName() on the ServletConfig. If the above is not met, null is returned.

param
inv The invocation object to process.
return
Servlet name or null.

        Object invInstance = inv.getInstance();
        
        if (invInstance instanceof HttpServlet) {

            HttpServlet thisServlet = (HttpServlet)invInstance;
            ServletConfig svc = thisServlet.getServletConfig();

            if (svc != null) {
                return thisServlet.getServletName();
            }
        }
        return null;
    
public com.sun.enterprise.deployment.WebBundleDescriptorgetWebDescriptor()

        return webDesc;
    
WebSecurityManagergetWebSecurityManager(boolean logNull)

	if (webSecurityManager == null) {
	    synchronized(this) {
		webSecurityManager = webSecurityManagerFactory.
		    getWebSecurityManager(CONTEXT_ID);
	    }
	    if (webSecurityManager == null && logNull) {
		String msg = smRA.getString("realmAdapter.noWebSecMgr", CONTEXT_ID);
		_logger.warning(msg);
	    }
	}

	return webSecurityManager;
    
public booleanhasResourcePermission(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response, org.apache.catalina.deploy.SecurityConstraint[] constraints, org.apache.catalina.Context context)
Perform access control based on the specified authorization constraint. Return true if this constraint is satisfied and processing should continue, or false otherwise.

param
request Request we are processing
param
response Response we are creating
param
constraint Security constraint we are enforcing
param
The Context to which client of this class is attached.
exception
IOException if an input/output error occurs

        boolean isGranted = false;
        try {
            isGranted = invokeWebSecurityManager(
                request, response, constraints);
        } catch(IOException iex) {
            throw iex;
        } catch(Throwable ex) {
            ((HttpServletResponse) response.getResponse()).sendError
                    (HttpServletResponse.SC_SERVICE_UNAVAILABLE);
            response.setDetailMessage(sm.getString("realmBase.forbidden"));
            return isGranted;
        }
          
        if ( isGranted ){
            return isGranted;
        } else {
            ((HttpServletResponse) response.getResponse()).sendError
                    (HttpServletResponse.SC_FORBIDDEN);
            response.setDetailMessage(sm.getString("realmBase.forbidden"));
            // invoking secureResponse
            invokePostAuthenticateDelegate(request, response, context);
            return isGranted;
        }
    
public booleanhasRole(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response, java.security.Principal principal, java.lang.String role)
Check if the given principal has the provided role. Returns true if the principal has the specified role, false otherwise.

return
true if the principal has the specified role.
param
request Request we are processing
param
response Response we are creating
param
the principal
param
the role

        WebSecurityManager secMgr = getWebSecurityManager(true);
	if (secMgr == null) {
	    return false;
	}

        //add HttpResponse and HttpResponse to the parameters, and remove
        //instance variable currentRequest from this class. References to
        //this.currentRequest are also removed from other methods.
        //String servletName = getResourceName( currentRequest.getRequestURI(),
        //                                      currentRequest.getContextPath());
        HttpServletRequest hrequest = (HttpServletRequest) request;
        String servletName = getResourceName( hrequest.getRequestURI(), 
                                              hrequest.getContextPath());
        //END OF SJSAS 6232464 
        
        // First try with the request.
        boolean isGranted = 
            secMgr.hasRoleRefPermission(servletName, role, principal);
        
        if (!isGranted){
            // START S1AS8PE 4966609
            // This case occurs when a direct call is made
            // to a jsp instead of using the server-name element defined in web.xml
            servletName = getCanonicalName(hrequest);

            // If we can't find any servletMapping for a resource
            // (usually a jsp), return false. 
            if (servletName.equalsIgnoreCase(UNCONSTRAINED)){
                if(_logger.isLoggable(Level.INFO)){
                    _logger.log(Level.INFO,
                        "Unable to find a <servlet-name> element which map: " 
                            + hrequest.getRequestURI());
                }

                /*
                 * For every security role in the web application add a
                 * WebRoleRefPermission to the corresponding role. The name of all such
                 * permissions shall be the empty string, and the actions of each 
                 * permission shall be the corresponding role name. When checking a 
                 * WebRoleRefPermission from a JSP not mapped to a servlet, use a 
                 * permission with the empty string as its name
                 * and with the argument to isUserInRole as its actions
                 */            
                isGranted = secMgr.hasRoleRefPermission("", role, principal);

                // END S1AS8PE 4966609
            } else {
                isGranted = secMgr.hasRoleRefPermission(servletName, 
                                                               role, 
                                                               principal);
            }
        }
 
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine( "Checking if servlet " + servletName 
                        + " with principal " + principal 
                        + " has role " + role
                        + " isGranted: " + isGranted);
        }
        
        return isGranted;
        
    
public booleanhasUserDataPermission(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response, org.apache.catalina.deploy.SecurityConstraint[] constraints)
Enforce any user data constraint required by the security constraint guarding this request URI. Return true if this constraint was not violated and processing should continue, or false if we have created a response already.

param
request Request we are processing
param
response Response we are creating
param
constraint Security constraint being checked
exception
IOException if an input/output error occurs

        HttpServletRequest hrequest = (HttpServletRequest)request;
        if ( hrequest.getServletPath() == null){
            request.setServletPath( 
                getResourceName( hrequest.getRequestURI(), 
                                hrequest.getContextPath()));
        }
       
        if(_logger.isLoggable(Level.FINE)){
            _logger.fine("[Web-Security][ hasUserDataPermission ] Principal: " 
                        + hrequest.getUserPrincipal() 
                        + " ContextPath: " 
                        + hrequest.getContextPath());    
        }
        
        if (request.getRequest().isSecure()) {            
            if(_logger.isLoggable(Level.FINE))
                _logger.fine("[Web-Security] request.getRequest().isSecure(): " + request.getRequest().isSecure());   
            return true;
        }
        
        WebSecurityManager secMgr = getWebSecurityManager(true);
	if (secMgr == null) {
	    return false;
	}

        int isGranted = 0;
        try {
            isGranted = secMgr.hasUserDataPermission(hrequest);
        } catch (IllegalArgumentException e) {
            //end the request after getting IllegalArgumentException while checking
            //user data permission
            String msg = smRA.getString("realmAdapter.badRequest", e.getMessage());
            _logger.warning(msg);
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, msg, e);
            }
            ((HttpServletResponse) response.getResponse()).sendError
                (HttpServletResponse.SC_BAD_REQUEST, msg);
            return false;
        }
        
        // Only redirect if we are sure the user will be granted.
        // See bug 4947698 

        // This method will return:
        // 1  - if granted
        // 0  - if not granted
        // -1 - if the current transport is not granted, but a redirection can occur
        //      so the grand will succeed.
        if ( isGranted == -1 ){
            if(_logger.isLoggable(Level.FINE))
                _logger.fine( "[Web-Security] redirecting using SSL");
            return redirect(request, response);
        } 
        
        if (isGranted == 0){
            ((HttpServletResponse) response.getResponse()).sendError
                (HttpServletResponse.SC_FORBIDDEN,
                    sm.getString("realmBase.forbidden")); 
            return false;
        }

        return true;
     
public booleaninvokeAuthenticateDelegate(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response, org.apache.catalina.Context context, org.apache.catalina.Authenticator authenticator)
Authenticates the user making this request, based on the specified login configuration. Return true if any specified requirements have been satisfied, or false if we have created a response challenge already.

param
request Request we are processing
param
response Response we are creating
param
context The Context to which client of this class is attached.
param
authenticantion the current authenticator.
exception
IOException if an input/output error occurs


        boolean result = false;
	LoginConfig config = context.getLoginConfig();
        ServerAuthConfig serverAuthConfig = null;
        try {
            if (helper != null) {
                serverAuthConfig = helper.getServerAuthConfig();
            }
        } catch(Exception ex) {
            IOException iex = new IOException();
            iex.initCause(ex);
            throw iex;
        }   
        if (serverAuthConfig != null) {
            //JSR 196 is enabled for this application
            result = validate(request,response, config, authenticator);
        } else {
            //jsr196 is not enabled.  Use the current authenticator.
            result = ((AuthenticatorBase) authenticator).authenticate(
                request, response, config);
        }
        return result;
    
public booleaninvokePostAuthenticateDelegate(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response, org.apache.catalina.Context context)
Post authentication for given request and response.

param
request Request we are processing
param
response Response we are creating
param
context The Context to which client of this class is attached.
exception
IOException if an input/output error occurs


        boolean result = false;
        ServerAuthContext sAC = null;
        try {
            if (helper != null) {
                HttpServletRequest req = (HttpServletRequest)request.getRequest();
                MessageInfo messageInfo =
                        (MessageInfo)req.getAttribute(MESSAGE_INFO);
                if (messageInfo != null) {
                    //JSR 196 is enabled for this application
                    sAC = (ServerAuthContext)
                            messageInfo.getMap().get(SERVER_AUTH_CONTEXT);
                    if (sAC != null) {
                        AuthStatus authStatus = 
                                sAC.secureResponse(messageInfo,
                                    null); //null serviceSubject
                        result = AuthStatus.SUCCESS.equals(authStatus);
                    }
                } 
            }
        } catch(AuthException ex) {
            IOException iex = new IOException();
            iex.initCause(ex);
            throw iex;
        } finally {
            if (helper != null && sAC != null) {
                if (request instanceof HttpRequestWrapper) {
                    request.removeNote(Globals.WRAPPED_REQUEST);
                }
                if (response instanceof HttpResponseWrapper) {
                    request.removeNote(Globals.WRAPPED_RESPONSE);
                }
            }
        }   
        return result;
    
private booleaninvokeWebSecurityManager(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response, org.apache.catalina.deploy.SecurityConstraint[] constraints)
Invokes WebSecurityManager to perform access control check. Return true if permission is granted, or false otherwise.

param
request Request we are processing
param
response Response we are creating
param
constraint Security constraint we are enforcing
exception
IOException if an input/output error occurs


        // allow access to form login related pages and targets
        // and the "j_security_check" action
        boolean evaluated = false;
        try {
            rwLock.readLock().lock();
            evaluated = contextEvaluated;
        } finally {
            rwLock.readLock().unlock();
        }

        if (!evaluated) {
            try {
                rwLock.writeLock().lock();
                if (!contextEvaluated) {
                    // get Context here as preAuthenticateCheck does not have it
                    // and our Container is always a Context
                    Context context = (Context)getContainer();
                    LoginConfig config = context.getLoginConfig();
                    if ((config != null) &&
                            (Constants.FORM_METHOD.equals(config.getAuthMethod()))) {
                        loginPage = config.getLoginPage();
                        errorPage = config.getErrorPage();
                    }
                    contextEvaluated = true;
                }
            } finally {
                rwLock.writeLock().unlock();
            }
        }

        if (loginPage != null || errorPage != null) {
            String requestURI = request.getRequestPathMB().toString();
            if(_logger.isLoggable(Level.FINE)) {
                _logger.fine("[Web-Security]  requestURI: " + requestURI + 
                        " loginPage: " + loginPage);
            }
            if (loginPage != null && loginPage.equals(requestURI)) {
                if(_logger.isLoggable(Level.FINE)) {
                    _logger.fine(" Allow access to login page " + loginPage);
                }
                return true;
            }
            else if (errorPage != null && errorPage.equals(requestURI)) {
                if(_logger.isLoggable(Level.FINE)) {
                    _logger.fine(" Allow access to error page " + errorPage);
                }
                return true;
            }

            else if (requestURI.endsWith(Constants.FORM_ACTION)) {
                if(_logger.isLoggable(Level.FINE)) {
		    _logger.fine(" Allow access to username/password submission");
                }
                return true;
            }
        }

        HttpServletRequest hrequest = (HttpServletRequest)request;
                
        if ( hrequest.getServletPath() == null){
            request.setServletPath( getResourceName( hrequest.getRequestURI(), 
                    hrequest.getContextPath()));
        }
                
        if(_logger.isLoggable(Level.FINE))
            _logger.fine("[Web-Security] [ hasResourcePermission ] Principal: " 
                + hrequest.getUserPrincipal() + " ContextPath: " + hrequest.getContextPath());

        WebSecurityManager secMgr = getWebSecurityManager(true);
	if (secMgr == null) {
	    return false;
	}
        return secMgr.hasResourcePermission(hrequest);
    
public booleanisSecurityExtensionEnabled()
Return true if a Security Extension is available.

return
true if a Security Extension is available.

        if (helper == null) {
            return false;
        } else {
            try {
                return (helper.getServerAuthConfig() != null);
            } catch(Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    
private voidloginForRunAs(java.lang.String principal)

	LoginContextDriver.loginPrincipal (principal, _realmName);    
    
public voidlogout()

        setSecurityContext(null);
    
public voidpostSetRunAsIdentity(com.sun.enterprise.ComponentInvocation inv)
Attempts to restore old SecurityContext (but fails).

In theory this method seems to attempt to check if a run-as principal was set by preSetRunAsIdentity() (based on the indirect assumption that if the servlet in the given invocation has a run-as this must've been the case). If so, it retrieves the oldSecurityContext from the invocation object and set it in the SecurityContext.

The problem is that the invocation object is not the same object as was passed in to preSetRunAsIdentity() so it will never contain the right info - see bug 4757733.

In practice it means this method only ever sets the SecurityContext to null (if run-as matched) or does nothing. In particular note the implication that it will be set to null after a run-as invocation completes. This behavior will be retained for the time being for consistency with RI. It must be fixed later.

param
inv The invocation object to process.


        String name=this.getServletName(inv);
        if (name == null) {
            return;
        }

        String runAs = (String)runAsPrincipals.get(name);
        if (runAs != null) {
            setSecurityContext (inv.getOldSecurityContext ()); // always null

        }
    
public intpreAuthenticateCheck(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response, org.apache.catalina.deploy.SecurityConstraint[] constraints, boolean disableProxyCaching, boolean securePagesWithPragma, boolean ssoEnabled)
Checks whether or not authentication is needed. Returns an int, one of AUTHENTICATE_NOT_NEEDED, AUTHENTICATE_NEEDED, or AUTHENTICATED_NOT_AUTHORIZED

param
request Request we are processing
param
response Response we are creating
param
constraints Security constraint we are enforcing
param
disableProxyCaching whether or not to disable proxy caching for protected resources.
param
securePagesWithPragma true if we add headers which are incompatible with downloading office documents in IE under SSL but which fix a caching problem in Mozilla.
param
ssoEnabled true if sso is enabled
exception
IOException if an input/output error occurs

        boolean isGranted = false;

        try {
            if (helper != null && helper.getServerAuthConfig() != null) {
                return Realm.AUTHENTICATE_NEEDED;
            }

            isGranted = invokeWebSecurityManager(
                request, response, constraints);
        } catch(IOException iex) {
            throw iex;
        } catch(Throwable ex) {
            ((HttpServletResponse) response.getResponse()).sendError
                    (HttpServletResponse.SC_SERVICE_UNAVAILABLE);
            response.setDetailMessage(sm.getString("realmBase.forbidden"));
            return Realm.AUTHENTICATED_NOT_AUTHORIZED;
        }
        
        if(isGranted) {
            HashMap sharedState = null;
            boolean delegateSessionMgmt = false;
            //XXX Keep it for reference
            /*
  	    if (this.sAC != null) {
                sharedState = new HashMap();
                try {
                    delegateSessionMgmt = this.sAC.managesSessions(sharedState);
                } catch (AuthException ae) {
                    delegateSessionMgmt = false;
                }
            }

            if (delegateSessionMgmt) {      
                if (validate(request, response, null, null)) {
                    disableProxyCaching(request, response, disableProxyCaching,
                        securePagesWithPragma);
                }
            } else if( ((HttpServletRequest) request).getUserPrincipal() != null) {
            */
            if( ((HttpServletRequest) request).getUserPrincipal() != null) {
                disableProxyCaching(request, response, disableProxyCaching,
                    securePagesWithPragma);
                if (ssoEnabled) {
                    HttpServletRequest hreq =
                        (HttpServletRequest)request.getRequest();
                    WebSecurityManager webSecMgr = getWebSecurityManager(true);
                    if (!webSecMgr.permitAll(hreq)) {
                        //create a session for protected sso association
                        hreq.getSession(true);
                    }
                }
            }
            return Realm.AUTHENTICATE_NOT_NEEDED;
        } else if(((HttpServletRequest) request).getUserPrincipal() != null){
            ((HttpServletResponse) response.getResponse()).sendError
                    (HttpServletResponse.SC_FORBIDDEN);
            response.setDetailMessage(sm.getString("realmBase.forbidden"));
            return Realm.AUTHENTICATED_NOT_AUTHORIZED;
        } else {
            disableProxyCaching(request, response, disableProxyCaching,securePagesWithPragma);
            return Realm.AUTHENTICATE_NEEDED;
        }
    
public voidpreSetRunAsIdentity(com.sun.enterprise.ComponentInvocation inv)
Set the run-as principal into the SecurityContext when needed.

This method will attempt to obtain the name of the servlet from the ComponentInvocation. Note that there may not be one since this gets called also during internal processing (not clear..) not just part of servlet requests. However, if it is not a servlet request there is no need (or possibility) to have a run-as setting so no further action is taken.

If the servlet name is present the runAsPrincipals cache is checked to find the run-as principal to use (if any). If one is set, the SecurityContext is switched to this principal.

param
inv The invocation object to process.


        String name=this.getServletName(inv);
        if (name == null) {
            return;
        }

        String runAs = (String)runAsPrincipals.get(name);
        
        if (runAs != null) {
            // The existing SecurityContext is saved - however, this seems
            // meaningless - see bug 4757733. For now, keep it unchanged
            // in case there are some dependencies elsewhere in RI.
            SecurityContext old = getSecurityContext();
            inv.setOldSecurityContext(old);

            // Set the run-as principal into SecurityContext
            loginForRunAs(runAs);
            
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine("run-as principal for " + name +
                             " set to: "+ runAs);
            }
        }
    
private booleanredirect(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response)

        // Initialize variables we need to determine the appropriate action
        HttpServletRequest hrequest =
            (HttpServletRequest) request.getRequest();
        HttpServletResponse hresponse =
            (HttpServletResponse) response.getResponse();
        int redirectPort = request.getConnector().getRedirectPort();

        // Is redirecting disabled?
        if (redirectPort <= 0) {
            if(_logger.isLoggable(Level.INFO))
                _logger.fine("[Web-Security]  SSL redirect is disabled");

            hresponse.sendError
                (HttpServletResponse.SC_FORBIDDEN, hrequest.getRequestURI());
            return (false);
        }
       
        String protocol = "https";
        String host = hrequest.getServerName();
        StringBuffer file = new StringBuffer(hrequest.getRequestURI());
        String requestedSessionId = hrequest.getRequestedSessionId();
        if ((requestedSessionId != null) &&
            hrequest.isRequestedSessionIdFromURL()) {
            file.append(";jsessionid=");
            file.append(requestedSessionId);
        }
        String queryString = hrequest.getQueryString();
        if (queryString != null) {
            file.append('?");
            file.append(queryString);
        }
        URL url = null;
        try {
            url = new URL(protocol, host, redirectPort, file.toString());
            hresponse.sendRedirect(url.toString());
            return (false);
        } catch (MalformedURLException e) {
            hresponse.sendError
                (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                 hrequest.getRequestURI());
            return (false);
        }
    
public voidsetRealmName(java.lang.String realmName)

        // do nothing since this is done when initializing the Realm.
    
private voidsetSecurityContext(com.sun.enterprise.security.SecurityContext sc)

        SecurityContext.setCurrent (sc);
    
public voidsetVirtualServer(org.apache.catalina.Container container)
Sets the virtual server on which the web module (with which this RealmAdapter is associated with) has been deployed.

param
container The virtual server

        this.virtualServer = container;
        this.helper = getConfigHelper();
    
private booleanvalidate(org.apache.catalina.HttpRequest request, org.apache.catalina.HttpResponse response, org.apache.catalina.deploy.LoginConfig config, org.apache.catalina.Authenticator authenticator)


        HttpServletRequest req = (HttpServletRequest)request.getRequest();
        HttpServletResponse res = (HttpServletResponse)response.getResponse();

        Subject subject = new Subject();

	MessageInfo messageInfo = new HttpMessageInfo(req, res);

        boolean rvalue = false;
        boolean isMandatory = true;
        try {
            WebSecurityManager webSecMgr = getWebSecurityManager(true);
            isMandatory = !webSecMgr.permitAll(req);
            if (isMandatory) {
                messageInfo.getMap().put(HttpServletConstants.IS_MANDATORY,
                    Boolean.TRUE.toString());
            }
            ServerAuthContext sAC =
                    helper.getServerAuthContext(messageInfo,
                        null); // null serviceSubject
            if (sAC != null) {
                AuthStatus authStatus = 
                        sAC.validateRequest(messageInfo, subject,
                            null); // null serviceSubject
                rvalue = AuthStatus.SUCCESS.equals(authStatus);

                if (rvalue) { // cache it only if validateRequest = true
                    messageInfo.getMap().put(SERVER_AUTH_CONTEXT, sAC);
                    req.setAttribute(MESSAGE_INFO, messageInfo);
                }
            } else {
		throw new AuthException("null ServerAuthContext");
	    }
        } catch(AuthException ae) {
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE,
                "JAMC: http msg authentication fail",ae);
            }
            res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }

        if (rvalue) {
            Set principalSet = subject.getPrincipals();
            // must be at least one new principal to establish 
	    // non-default security context
            if (principalSet != null && !principalSet.isEmpty()) {
                SecurityContext ctx = new SecurityContext(subject);
                //XXX assuming no null principal here
		Principal p = ctx.getCallerPrincipal();
		WebPrincipal wp = new WebPrincipal(p,ctx);
		try {
                    //XXX Keep it for reference
                    /*
		    if (this.sAC.managesSessions(sharedState)) {
			// registration (via proxy) does not occur
			// if context manages sessions
			// record authentication information in the request
			request.setAuthType(PROXY_AUTH_TYPE);
			request.setUserPrincipal(wp);
		    } else {
			AuthenticatorProxy proxy = 
			    new AuthenticatorProxy(authenticator,wp);
			proxy.authenticate(request,response,config);
		    }
                    */
                    String authType = (String)messageInfo.getMap().get(
                            HttpServletHelper.AUTH_TYPE);
                    boolean register = messageInfo.getMap().containsKey(
                            HttpServletConstants.REGISTER_WITH_AUTHENTICATOR);

                    if (authType == null && config != null &&
                            config.getAuthMethod() != null) {
                        authType = config.getAuthMethod();
                    }

                    if (register) {
                        AuthenticatorProxy proxy = new AuthenticatorProxy
                               (authenticator, wp, authType);
                        proxy.authenticate(request,response,config);
                    } else {
                        request.setAuthType((authType == null) ?
                                PROXY_AUTH_TYPE: authType);
                        request.setUserPrincipal(wp);
                    }
		} catch (LifecycleException le) {
		    _logger.log(Level.SEVERE,"[Web-Security] unable to register session",le);
		
                                }

                HttpServletRequest newRequest = (HttpServletRequest) 
                    messageInfo.getRequestMessage();
                if (newRequest != req) {
                    request.setNote(Globals.WRAPPED_REQUEST, 
                            new HttpRequestWrapper(request, newRequest));
                }

                HttpServletResponse newResponse = (HttpServletResponse) 
                    messageInfo.getResponseMessage();
                if (newResponse != res) {
                    request.setNote(Globals.WRAPPED_RESPONSE, 
                            new HttpResponseWrapper(response,newResponse));
                }

	    } else if (isMandatory) {
		rvalue = false;
	    }
	}
        return rvalue;