/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2014 Oracle and/or its affiliates. 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_1_1.html * or packager/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 packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [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. * * * This file incorporates work covered by the following copyright and * permission notice: * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Portions Copyright [2016] [Payara Foundation and/or its affiliates] package org.apache.catalina.authenticator; import org.apache.catalina.*; import org.apache.catalina.core.StandardHost; import org.apache.catalina.core.StandardServer; import org.apache.catalina.deploy.LoginConfig; import org.apache.catalina.deploy.SecurityConstraint; import org.apache.catalina.valves.ValveBase; import org.glassfish.logging.annotation.LogMessageInfo; import org.glassfish.web.valve.GlassFishValve; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Method; import java.security.Principal; import java.text.MessageFormat; import java.util.Random; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; /** * Basic implementation of the <b>Valve</b> interface that enforces the * <code><security-constraint></code> elements in the web application * deployment descriptor. This functionality is implemented as a Valve * so that it can be ommitted in environments that do not require these * features. Individual implementations of each supported authentication * method can subclass this base class as required. * <p> * <b>USAGE CONSTRAINT</b>: When this class is utilized, the Context to * which it is attached (or a parent Container in a hierarchy) must have an * associated Realm that can be used for authenticating users and enumerating * the roles to which they have been assigned. * <p> * <b>USAGE CONSTRAINT</b>: This Valve is only useful when processing HTTP * requests. Requests of any other type will simply be passed through. * * @author Craig R. McClanahan * @version $Revision: 1.17.6.3 $ $Date: 2008/04/17 18:37:04 $ */ public abstract class AuthenticatorBase extends ValveBase /** CR 6411114 (Lifecycle implementation moved to ValveBase) implements Authenticator, Lifecycle { */ // START CR 6411114 implements Authenticator { // END CR 6411114 // ----------------------------------------------------- Static Variables protected static final Logger log = StandardServer.log; protected static final ResourceBundle rb = log.getResourceBundle(); @LogMessageInfo( message = "Configuration error: Must be attached to a Context", level = "WARNING" ) public static final String CONFIG_ERROR_MUST_ATTACH_TO_CONTEXT = "AS-WEB-CORE-00001"; @LogMessageInfo( message = "Authenticator[{0}]: {1}", level = "INFO" ) public static final String AUTHENTICATOR_INFO = "AS-WEB-CORE-00002"; @LogMessageInfo( message = "Exception getting debug value", level = "SEVERE", cause = "Could not get the method or invoke underlying method", action = "Verify the existence of such method and access permission" ) public static final String GETTING_DEBUG_VALUE_EXCEPTION = "AS-WEB-CORE-00003"; @LogMessageInfo( message = "Login failed", level = "WARNING" ) public static final String LOGIN_FAIL = "AS-WEB-CORE-00535"; /** * Descriptive information about this implementation. */ protected static final String info = "org.apache.catalina.authenticator.AuthenticatorBase/1.0"; /** * The number of random bytes to include when generating a * session identifier. */ protected static final int SESSION_ID_BYTES = 16; /** * Authentication header */ protected static final String AUTH_HEADER_NAME = "WWW-Authenticate"; /** * Default authentication realm name. */ protected static final String REALM_NAME = "Authentication required"; // ----------------------------------------------------- Instance Variables /** * Should a session always be used once a user is authenticated? This may * offer some performance benefits since the session can then be used to * cache the authenticated Principal, hence removing the need to * authenticate the user via the Realm on every request. This may be of help * for combinations such as BASIC authentication used with the JNDIRealm or * DataSourceRealms. However there will also be the performance cost of * creating and GC'ing the session. By default, a session will not be * created. */ protected boolean alwaysUseSession = false; /** * Should we cache authenticated Principals if the request is part of * an HTTP session? */ protected boolean cache = true; /** * Should the session ID, if any, be changed upon a successful * authentication to prevent a session fixation attack? */ protected boolean changeSessionIdOnAuthentication = true; /** * The Context to which this Valve is attached. */ protected Context context = null; /** * A String initialization parameter used to increase the entropy of * the initialization of our random number generator. */ protected String entropy = null; /** * Flag to determine if we disable proxy caching, or leave the issue * up to the webapp developer. */ protected boolean disableProxyCaching = true; /** * The lifecycle event support for this component. */ /** CR 6411114 (Lifecycle implementation moved to ValveBase) protected LifecycleSupport lifecycle = new LifecycleSupport(this); */ /** * A random number generator to use when generating session identifiers. */ protected Random random = null; /** * The Java class name of the random number generator class to be used * when generating session identifiers. */ protected String randomClass = java.security.SecureRandom.class.getName(); /** * The SingleSignOn implementation in our request processing chain, * if there is one. */ protected SingleSignOn sso = null; /** * Has this component been started? */ /** CR 6411114 (Lifecycle implementation moved to ValveBase) protected boolean started = false; */ /** * "Expires" header always set to Date(1), so generate once only */ //START SJSAS 6202703 /* private static final String DATE_ONE = (new SimpleDateFormat(DateTool.HTTP_RESPONSE_DATE_HEADER, Locale.US)).format(new Date(1)); */ //END SJSAS 6202703 /** * Flag to determine if we disable proxy caching with headers incompatible * with IE */ protected boolean securePagesWithPragma = true; // ------------------------------------------------------------- Properties public boolean getAlwaysUseSession() { return alwaysUseSession; } public void setAlwaysUseSession(boolean alwaysUseSession) { this.alwaysUseSession = alwaysUseSession; } /** * Return the cache authenticated Principals flag. */ public boolean getCache() { return (this.cache); } /** * Set the cache authenticated Principals flag. * * @param cache The new cache flag */ public void setCache(boolean cache) { this.cache = cache; } /** * Return the Container to which this Valve is attached. */ public Container getContainer() { return (this.context); } /** * Set the Container to which this Valve is attached. * * @param container The container to which we are attached */ public void setContainer(Container container) { if (!(container instanceof Context)) throw new IllegalArgumentException (rb.getString(CONFIG_ERROR_MUST_ATTACH_TO_CONTEXT)); super.setContainer(container); this.context = (Context) container; this.securePagesWithPragma = context.isSecurePagesWithPragma(); } /** * Return the debugging detail level for this component. */ public int getDebug() { return (this.debug); } /** * Set the debugging detail level for this component. * * @param debug The new debugging detail level */ public void setDebug(int debug) { this.debug = debug; } /** * Return the entropy increaser value, or compute a semi-useful value * if this String has not yet been set. */ public String getEntropy() { // Calculate a semi-useful value if this has not been set if (this.entropy == null) setEntropy(this.toString()); return (this.entropy); } /** * Set the entropy increaser value. * * @param entropy The new entropy increaser value */ public void setEntropy(String entropy) { this.entropy = entropy; } /** * Return descriptive information about this Valve implementation. */ @Override public String getInfo() { return (this.info); } /** * Return the random number generator class name. */ public String getRandomClass() { return (this.randomClass); } /** * Set the random number generator class name. * * @param randomClass The new random number generator class name */ public void setRandomClass(String randomClass) { this.randomClass = randomClass; } /** * Return the flag that states if we add headers to disable caching by * proxies. */ public boolean getDisableProxyCaching() { return disableProxyCaching; } /** * Set the value of the flag that states if we add headers to disable * caching by proxies. * @param nocache <code>true</code> if we add headers to disable proxy * caching, <code>false</code> if we leave the headers alone. */ public void setDisableProxyCaching(boolean nocache) { disableProxyCaching = nocache; } /** * Return the flag that states, if proxy caching is disabled, what headers * we add to disable the caching. */ public boolean isSecurePagesWithPragma() { return securePagesWithPragma; } /** * Set the value of the flag that states what headers we add to disable * proxy caching. * @param securePagesWithPragma <code>true</code> if we add headers which * are incompatible with downloading office documents in IE under SSL but * which fix a caching problem in Mozilla. */ public void setSecurePagesWithPragma(boolean securePagesWithPragma) { this.securePagesWithPragma = securePagesWithPragma; } /** * Return the flag that states if we should change the session ID of an * existing session upon successful authentication. * * @return <code>true</code> to change session ID upon successful * authentication, <code>false</code> to do not perform the change. */ public boolean isChangeSessionIdOnAuthentication() { return changeSessionIdOnAuthentication; } /** * Set the value of the flag that states if we should change the session ID * of an existing session upon successful authentication. * * @param changeSessionIdOnAuthentication * <code>true</code> to change session ID upon successful * authentication, <code>false</code> to do not perform the * change. */ public void setChangeSessionIdOnAuthentication( boolean changeSessionIdOnAuthentication) { this.changeSessionIdOnAuthentication = changeSessionIdOnAuthentication; } public SingleSignOn getSingleSignOn() { return sso; } public void setSingleSignOn(SingleSignOn sso) { this.sso = sso; } // --------------------------------------------------------- Public Methods /** * Enforce the security restrictions in the web application deployment * descriptor of our associated Context. * * @param request Request to be processed * @param response Response to be processed * * @exception IOException if an input/output error occurs * @exception ServletException if thrown by a processing element */ @Override public int invoke(Request request, Response response) throws IOException, ServletException { // START GlassFish 247 if (!context.getAvailable()) { try { ((HttpServletResponse) response.getResponse()) .sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); } catch (IllegalStateException e) { ; } catch (IOException e) { ; } return END_PIPELINE; } // END GlassFish 247 /* GlassFish 6386229 // If this is not an HTTP request, do nothing if (!(request instanceof HttpRequest) || !(response instanceof HttpResponse)) { return INVOKE_NEXT; } if (!(request.getRequest() instanceof HttpServletRequest) || !(response.getResponse() instanceof HttpServletResponse)) { return INVOKE_NEXT; } */ HttpRequest hrequest = (HttpRequest) request; HttpResponse hresponse = (HttpResponse) response; if (log.isLoggable(Level.FINE)) { String msg = "Security checking request " + ((HttpServletRequest) request.getRequest()).getMethod() + " " + ((HttpServletRequest) request.getRequest()).getRequestURI(); log.log(Level.FINE, msg); } LoginConfig config = this.context.getLoginConfig(); // Have we got a cached authenticated Principal to record? if (cache) { Principal principal = ((HttpServletRequest) request.getRequest()).getUserPrincipal(); if (principal == null) { Session session = getSession(hrequest); if (session != null) { principal = session.getPrincipal(); if (principal != null) { if (log.isLoggable(Level.FINE)) { String msg = "We have cached auth type " + session.getAuthType() + " for principal " + session.getPrincipal(); log.log(Level.FINE, msg); } hrequest.setAuthType(session.getAuthType()); hrequest.setUserPrincipal(principal); } } } } Realm realm = this.context.getRealm(); // Is this request URI subject to a security constraint? SecurityConstraint [] constraints = realm. findSecurityConstraints(hrequest, this.context); if ((constraints == null) /* && (!Constants.FORM_METHOD.equals(config.getAuthMethod())) */ ) { if (log.isLoggable(Level.FINE)) log.log(Level.FINE, " Not subject to any constraint"); return processSecurityCheck(hrequest,hresponse,config); } // Make sure that constrained resources are not cached by web proxies // or browsers as caching can provide a security hole //START SJSAS 6202703 //Moved to org.apache.catalina.realm.RealmBase /* HttpServletRequest hsrequest = (HttpServletRequest)hrequest.getRequest(); if (disableProxyCaching && !hsrequest.isSecure() && !"POST".equalsIgnoreCase(hsrequest.getMethod())) { HttpServletResponse sresponse = (HttpServletResponse) response.getResponse(); sresponse.setHeader("Pragma", "No-cache"); sresponse.setHeader("Cache-Control", "no-cache"); sresponse.setHeader("Expires", DATE_ONE); } */ //END SJSAS 6202703 if (log.isLoggable(Level.FINE)) log.log(Level.FINE, " Calling hasUserDataPermission()"); if (!realm.hasUserDataPermission(hrequest, hresponse, constraints)) { if (log.isLoggable(Level.FINE)) log.log(Level.FINE, " Failed hasUserDataPermission() test"); // ASSERT: Authenticator already set the appropriate // HTTP status code, so we do not have to do anything special return END_PIPELINE; } //START SJSAS 6202703 /* for(int i=0; i < constraints.length; i++) { // Authenticate based upon the specified login configuration if (constraints[i].getAuthConstraint()) { if (log.isDebugEnabled()) log.debug(" Calling authenticate()"); if (!authenticate(hrequest, hresponse, config)) { if (log.isDebugEnabled()) log.debug(" Failed authenticate() test"); //ASSERT: Authenticator already set the appropriate //HTTP status code, so we do not have to do anything special return END_PIPELINE; } else { break; } } } */ //END SJSAS 6202703 //START SJSAS 6202703 int preAuthenticateCheckResult = realm.preAuthenticateCheck( hrequest, hresponse, constraints, disableProxyCaching, securePagesWithPragma, (sso != null)); if(preAuthenticateCheckResult == Realm.AUTHENTICATE_NOT_NEEDED) { return processSecurityCheck(hrequest,hresponse,config); } else if(preAuthenticateCheckResult == Realm.AUTHENTICATE_NEEDED) { if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, " Calling authenticate()"); } boolean authenticateResult = realm.invokeAuthenticateDelegate( hrequest, hresponse, context, this, false); if(!authenticateResult) { if(log.isLoggable(Level.FINE)) { log.log(Level.FINE, " Failed authenticate() test"); } return END_PIPELINE; } } else if(preAuthenticateCheckResult == Realm.AUTHENTICATED_NOT_AUTHORIZED) { return END_PIPELINE; } //END SJSAS 6202703 if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, " Calling accessControl()"); } if (!realm.hasResourcePermission(hrequest, hresponse, constraints, this.context)) { if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, " Failed accessControl() test"); } // START IASRI 4823322 Auditor[] auditors = this.context.getAuditors(); if (auditors != null) { for (int j=0; j<auditors.length; j++) { auditors[j].webInvocation(hrequest, false); } } // END IASRI 4823322 /* * ASSERT: AccessControl method has already set the * appropriate HTTP status code, so we do not have to do * anything special */ return END_PIPELINE; } // START IASRI 4823322 Auditor[] auditors = this.context.getAuditors(); if (auditors != null) { boolean success=true; for (int j=0; j<auditors.length; j++) { try { auditors[j].webInvocation(hrequest, true); } catch (Exception e) { success=false; } } if (!success) { // fail authorization if auditor blew up return END_PIPELINE; } } // END IASRI 4823322 // Any and all specified constraints have been satisfied if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Successfully passed all security constraints"); return INVOKE_NEXT; } /** * A post-request processing implementation that does nothing. * * Very few Valves override this behaviour as most Valve logic * is used for request processing. */ @Override public void postInvoke(Request request, Response response) throws IOException, ServletException { Realm realm = this.context.getRealm(); HttpRequest hrequest = (HttpRequest) request; HttpResponse hresponse = (HttpResponse) response; /* * Check realm for null since app may have been undeployed by the * time its pipeline is invoked on the way out, in which case its * realm will have been set to null. See IT 6801 */ if (realm != null) { realm.invokePostAuthenticateDelegate(hrequest, hresponse, context); } } // ------------------------------------------------------ Protected Methods /** * Associate the specified single sign on identifier with the * specified Session. * * @param ssoId Single sign on identifier * @param ssoVersion Single sign on version * @param session Session to be associated */ protected void associate(String ssoId, long ssoVersion, Session session) { if (sso == null) return; sso.associate(ssoId, ssoVersion, session); } /** * Authenticate the user making this request, based on the specified * login configuration. Return <code>true</code> if any specified * constraint has been satisfied, or <code>false</code> if we have * created a response challenge already. * * @param request Request we are processing * @param response Response we are creating * @param config Login configuration describing how authentication * should be performed * * @exception IOException if an input/output error occurs */ //START SJSAS 6202703 /* protected abstract boolean authenticate(HttpRequest request, HttpResponse response, LoginConfig config) throws IOException; */ public abstract boolean authenticate(HttpRequest request, HttpResponse response, LoginConfig config) throws IOException; //END SJSAS 6202703 /** * Generate and return a new session identifier for the cookie that * identifies an SSO principal. */ protected synchronized String generateSessionId() { // Generate a byte array containing a session identifier byte bytes[] = new byte[SESSION_ID_BYTES]; getRandom().nextBytes(bytes); // Render the result as a String of hexadecimal digits StringBuilder result = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { byte b1 = (byte) ((bytes[i] & 0xf0) >> 4); byte b2 = (byte) (bytes[i] & 0x0f); if (b1 < 10) result.append((char) ('0' + b1)); else result.append((char) ('A' + (b1 - 10))); if (b2 < 10) result.append((char) ('0' + b2)); else result.append((char) ('A' + (b2 - 10))); } return (result.toString()); } /** * Return the random number generator instance we should use for * generating session identifiers. If there is no such generator * currently defined, construct and seed a new one. */ protected synchronized Random getRandom() { if (this.random == null) { try { Class clazz = Class.forName(randomClass); this.random = (Random) clazz.newInstance(); long seed = System.currentTimeMillis(); char entropy[] = getEntropy().toCharArray(); for (int i = 0; i < entropy.length; i++) { long update = ((byte) entropy[i]) << ((i % 8) * 8); seed ^= update; } this.random.setSeed(seed); } catch (Exception e) { this.random = new java.util.Random(); } } return (this.random); } /** * Return the internal Session that is associated with this HttpRequest, * or <code>null</code> if there is no such Session. * * @param request The HttpRequest we are processing */ protected Session getSession(HttpRequest request) { return (getSession(request, false)); } /** * Return the internal Session that is associated with this HttpRequest, * possibly creating a new one if necessary, or <code>null</code> if * there is no such session and we did not create one. * * @param request The HttpRequest we are processing * @param create Should we create a session if needed? */ protected Session getSession(HttpRequest request, boolean create) { return request.getSessionInternal(create); } /** * Log a message on the Logger associated with our Container (if any). * * @param message Message to be logged */ protected void log(String message) { org.apache.catalina.Logger logger = context.getLogger(); if (logger != null) { logger.log("Authenticator[" + context.getPath() + "]: " + message); } else { if (log.isLoggable(Level.INFO)) { log.log(Level.INFO, AUTHENTICATOR_INFO, new Object[] {context.getPath(), message}); } } } /** * Log a message on the Logger associated with our Container (if any). * * @param message Message to be logged * @param t Associated exception */ protected void log(String message, Throwable t) { org.apache.catalina.Logger logger = context.getLogger(); if (logger != null) { logger.log("Authenticator[" + context.getPath() + "]: " + message, t, org.apache.catalina.Logger.WARNING); } else { String msg = MessageFormat.format(rb.getString(AUTHENTICATOR_INFO), new Object[] {context.getPath(), message}); log.log(Level.WARNING, msg, t); } } /** * Register an authenticated Principal and authentication type in our * request, in the current session (if there is one), and with our * SingleSignOn valve, if there is one. Set the appropriate cookie * to be returned. * * @param request The servlet request we are processing * @param response The servlet response we are generating * @param principal The authenticated Principal to be registered * @param authType The authentication type to be registered * @param username Username used to authenticate (if any) * @param password Password used to authenticate (if any) */ protected void register(HttpRequest request, HttpResponse response, Principal principal, String authType, String username, char[] password) { if (log.isLoggable(Level.FINE)) { String pname = ((principal != null) ? principal.getName() : "[null principal]"); String msg = "Authenticated '" + pname + "' with type '" + authType + "'"; log.log(Level.FINE, msg); } // Cache the authentication information in our request request.setAuthType(authType); request.setUserPrincipal(principal); Session session = getSession(request, false); if (session != null && changeSessionIdOnAuthentication) { request.changeSessionId(); } else if (alwaysUseSession) { session = getSession(request, true); } // Cache the authentication information in our session, if any if (cache) { if (session != null) { session.setAuthType(authType); session.setPrincipal(principal); if (username != null) session.setNote(Constants.SESS_USERNAME_NOTE, username); else session.removeNote(Constants.SESS_USERNAME_NOTE); if (password != null) session.setNote(Constants.SESS_PASSWORD_NOTE, password); else session.removeNote(Constants.SESS_PASSWORD_NOTE); } } // Construct a cookie to be returned to the client if (sso == null) return; HttpServletRequest hreq = (HttpServletRequest) request.getRequest(); HttpServletResponse hres = (HttpServletResponse) response.getResponse(); // Use the connector's random number generator (if any) for // generating the session ID. If none, then fall back to the default // session ID generator. String value = request.generateSessionId(); if (value == null) { value = generateSessionId(); } Cookie cookie = new Cookie(Constants.SINGLE_SIGN_ON_COOKIE, value); cookie.setMaxAge(-1); cookie.setPath("/"); StandardHost host = (StandardHost) context.getParent(); if (host != null) { host.configureSingleSignOnCookieSecure(cookie, hreq); host.configureSingleSignOnCookieHttpOnly(cookie); } else { cookie.setSecure(hreq.isSecure()); } hres.addCookie(cookie); // Register this principal with our SSO valve /* BEGIN S1AS8 PE 4856080,4918627 sso.register(value, principal, authType, username, password); */ // BEGIN S1AS8 PE 4856080,4918627 String realm = context.getRealm().getRealmName(); // being here, an authentication just occurred using the realm assert(realm != null); sso.register(value, principal, authType, username, password, realm); // END S1AS8 PE 4856080,4918627 request.setNote(Constants.REQ_SSOID_NOTE, value); if (sso.isVersioningSupported()) { request.setNote(Constants.REQ_SSO_VERSION_NOTE, Long.valueOf(0)); } } @Override public void login(String username, char[] password, HttpRequest request) throws ServletException { Principal principal = doLogin(request, username, password); register(request, (HttpResponse)request.getResponse(), principal, getAuthMethod(), username, password); } protected abstract String getAuthMethod(); /** * Process the login request. * * @param request Associated request * @param username The user * @param password The password * @return The authenticated Principal * @throws ServletException */ protected Principal doLogin(HttpRequest request, String username, char[] password) throws ServletException { Principal p = context.getRealm().authenticate(username, password); if (p == null) { throw new ServletException(rb.getString(LOGIN_FAIL)); } return p; } @Override public void logout(HttpRequest request) throws ServletException { Session session = getSession(request); if (session != null) { session.setPrincipal(null); session.setAuthType(null); } // principal and authType set to null in the following register(request, (HttpResponse)request.getResponse(), null, null, null, null); } // ------------------------------------------------------ Private Methods private int processSecurityCheck(HttpRequest hrequest, HttpResponse hresponse, LoginConfig config) throws IOException { // Special handling for form-based logins to deal with the case // where the login form (and therefore the "j_security_check" URI // to which it submits) might be outside the secured area String contextPath = this.context.getPath(); String requestURI = hrequest.getDecodedRequestURI(); if (requestURI.startsWith(contextPath) && requestURI.endsWith(Constants.FORM_ACTION)) { if (!authenticate(hrequest, hresponse, config)) { if (log.isLoggable(Level.FINE)) { String msg = " Failed authenticate() test ??" + requestURI; log.log(Level.FINE, msg); } return END_PIPELINE; } } return INVOKE_NEXT; } // ------------------------------------------------------ Lifecycle Methods /** * Add a lifecycle event listener to this component. * * @param listener The listener to add */ /** CR 6411114 (Lifecycle implementation moved to ValveBase) public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } */ /** * Get the lifecycle listeners associated with this lifecycle. If this * Lifecycle has no listeners registered, a zero-length array is returned. */ /** CR 6411114 (Lifecycle implementation moved to ValveBase) public LifecycleListener[] findLifecycleListeners() { return lifecycle.findLifecycleListeners(); } */ /** * Remove a lifecycle event listener from this component. * * @param listener The listener to remove */ /** CR 6411114 (Lifecycle implementation moved to ValveBase) public void removeLifecycleListener(LifecycleListener listener) { lifecycle.removeLifecycleListener(listener); } */ /** * Prepare for the beginning of active use of the public methods of this * component. This method should be called after <code>configure()</code>, * and before any of the public methods of the component are utilized. * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException { // START CR 6411114 if (started) // Ignore multiple starts return; super.start(); // END CR 6411114 if ("org.apache.catalina.core.StandardContext".equals (context.getClass().getName())) { try { // XXX What is this ??? Class paramTypes[] = new Class[0]; Object paramValues[] = new Object[0]; Method method = context.getClass().getMethod("getDebug", paramTypes); Integer result = (Integer) method.invoke(context, paramValues); setDebug(result.intValue()); } catch (Exception e) { log.log(Level.SEVERE, GETTING_DEBUG_VALUE_EXCEPTION, e); } } /** CR 6411114 (Lifecycle implementation moved to ValveBase) started = true; */ // Look up the SingleSignOn implementation in our request processing // path, if there is one Container parent = context.getParent(); while ((sso == null) && (parent != null)) { if (!(parent instanceof Pipeline)) { parent = parent.getParent(); continue; } GlassFishValve valves[] = ((Pipeline) parent).getValves(); for (int i = 0; i < valves.length; i++) { if (valves[i] instanceof SingleSignOn) { sso = (SingleSignOn) valves[i]; break; } } if (sso == null) parent = parent.getParent(); } if (log.isLoggable(Level.FINE)) { if (sso != null) log.log(Level.FINE, "Found SingleSignOn Valve at " + sso); else log.log(Level.FINE, "No SingleSignOn Valve is present"); } } /** * Gracefully terminate the active use of the public methods of this * component. This method should be the last one called on a given * instance of this component. * * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ @Override public void stop() throws LifecycleException { // START CR 6411114 if (!started) // Ignore stop if not started return; // END CR 6411114 sso = null; // START CR 6411114 super.stop(); // END CR 6411114 } // BEGIN S1AS8 PE 4856062,4918627 /** * Set the name of the associated realm. This method does nothing by * default. * * @param name the name of the realm. */ public void setRealmName(String name) { } /** * Returns the name of the associated realm. Always returns null unless * subclass overrides behavior. * * @return realm name or null if not set. */ public String getRealmName() { return null; } // END S1AS8 PE 4856062,4918627 }