Source Code Cross Referenced for AuthenticatorBase.java in  » Web-Server » Rimfaxe-Web-Server » org » apache » catalina » authenticator » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Server » Rimfaxe Web Server » org.apache.catalina.authenticator 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/AuthenticatorBase.java,v 1.32 2002/06/09 02:19:41 remm Exp $
0003:         * $Revision: 1.32 $
0004:         * $Date: 2002/06/09 02:19:41 $
0005:         *
0006:         * ====================================================================
0007:         *
0008:         * The Apache Software License, Version 1.1
0009:         *
0010:         * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
0011:         * reserved.
0012:         *
0013:         * Redistribution and use in source and binary forms, with or without
0014:         * modification, are permitted provided that the following conditions
0015:         * are met:
0016:         *
0017:         * 1. Redistributions of source code must retain the above copyright
0018:         *    notice, this list of conditions and the following disclaimer.
0019:         *
0020:         * 2. Redistributions in binary form must reproduce the above copyright
0021:         *    notice, this list of conditions and the following disclaimer in
0022:         *    the documentation and/or other materials provided with the
0023:         *    distribution.
0024:         *
0025:         * 3. The end-user documentation included with the redistribution, if
0026:         *    any, must include the following acknowlegement:
0027:         *       "This product includes software developed by the
0028:         *        Apache Software Foundation (http://www.apache.org/)."
0029:         *    Alternately, this acknowlegement may appear in the software itself,
0030:         *    if and wherever such third-party acknowlegements normally appear.
0031:         *
0032:         * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
0033:         *    Foundation" must not be used to endorse or promote products derived
0034:         *    from this software without prior written permission. For written
0035:         *    permission, please contact apache@apache.org.
0036:         *
0037:         * 5. Products derived from this software may not be called "Apache"
0038:         *    nor may "Apache" appear in their names without prior written
0039:         *    permission of the Apache Group.
0040:         *
0041:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0042:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0043:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0044:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0045:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0046:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0047:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0048:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0049:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0050:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0051:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0052:         * SUCH DAMAGE.
0053:         * ====================================================================
0054:         *
0055:         * This software consists of voluntary contributions made by many
0056:         * individuals on behalf of the Apache Software Foundation.  For more
0057:         * information on the Apache Software Foundation, please see
0058:         * <http://www.apache.org/>.
0059:         *
0060:         * [Additional notices, if required by prior licensing conditions]
0061:         *
0062:         */
0063:
0064:        package org.apache.catalina.authenticator;
0065:
0066:        import java.io.IOException;
0067:        import java.lang.reflect.Method;
0068:        import java.net.MalformedURLException;
0069:        import java.net.URL;
0070:        import java.security.MessageDigest;
0071:        import java.security.NoSuchAlgorithmException;
0072:        import java.security.Principal;
0073:        import java.util.Random;
0074:        import javax.servlet.ServletException;
0075:        import javax.servlet.http.Cookie;
0076:        import javax.servlet.http.HttpServletRequest;
0077:        import javax.servlet.http.HttpServletResponse;
0078:        import javax.servlet.http.HttpSession;
0079:        import org.apache.catalina.Authenticator;
0080:        import org.apache.catalina.Container;
0081:        import org.apache.catalina.Context;
0082:        import org.apache.catalina.HttpRequest;
0083:        import org.apache.catalina.HttpResponse;
0084:        import org.apache.catalina.Lifecycle;
0085:        import org.apache.catalina.LifecycleEvent;
0086:        import org.apache.catalina.LifecycleException;
0087:        import org.apache.catalina.LifecycleListener;
0088:        import org.apache.catalina.Logger;
0089:        import org.apache.catalina.Manager;
0090:        import org.apache.catalina.Pipeline;
0091:        import org.apache.catalina.Realm;
0092:        import org.apache.catalina.Request;
0093:        import org.apache.catalina.Response;
0094:        import org.apache.catalina.Session;
0095:        import org.apache.catalina.Valve;
0096:        import org.apache.catalina.ValveContext;
0097:        import org.apache.catalina.deploy.LoginConfig;
0098:        import org.apache.catalina.deploy.SecurityConstraint;
0099:        import org.apache.catalina.util.LifecycleSupport;
0100:        import org.apache.catalina.util.RequestUtil;
0101:        import org.apache.catalina.util.StringManager;
0102:        import org.apache.catalina.valves.ValveBase;
0103:
0104:        /**
0105:         * Basic implementation of the <b>Valve</b> interface that enforces the
0106:         * <code>&lt;security-constraint&gt;</code> elements in the web application
0107:         * deployment descriptor.  This functionality is implemented as a Valve
0108:         * so that it can be ommitted in environments that do not require these
0109:         * features.  Individual implementations of each supported authentication
0110:         * method can subclass this base class as required.
0111:         * <p>
0112:         * <b>USAGE CONSTRAINT</b>:  When this class is utilized, the Context to
0113:         * which it is attached (or a parent Container in a hierarchy) must have an
0114:         * associated Realm that can be used for authenticating users and enumerating
0115:         * the roles to which they have been assigned.
0116:         * <p>
0117:         * <b>USAGE CONSTRAINT</b>:  This Valve is only useful when processing HTTP
0118:         * requests.  Requests of any other type will simply be passed through.
0119:         *
0120:         * @author Craig R. McClanahan
0121:         * @version $Revision: 1.32 $ $Date: 2002/06/09 02:19:41 $
0122:         */
0123:
0124:        public abstract class AuthenticatorBase extends ValveBase implements 
0125:                Authenticator, Lifecycle {
0126:
0127:            // ----------------------------------------------------- Instance Variables
0128:
0129:            /**
0130:             * The default message digest algorithm to use if we cannot use
0131:             * the requested one.
0132:             */
0133:            protected static final String DEFAULT_ALGORITHM = "MD5";
0134:
0135:            /**
0136:             * The number of random bytes to include when generating a
0137:             * session identifier.
0138:             */
0139:            protected static final int SESSION_ID_BYTES = 16;
0140:
0141:            /**
0142:             * The message digest algorithm to be used when generating session
0143:             * identifiers.  This must be an algorithm supported by the
0144:             * <code>java.security.MessageDigest</code> class on your platform.
0145:             */
0146:            protected String algorithm = DEFAULT_ALGORITHM;
0147:
0148:            /**
0149:             * Should we cache authenticated Principals if the request is part of
0150:             * an HTTP session?
0151:             */
0152:            protected boolean cache = true;
0153:
0154:            /**
0155:             * The Context to which this Valve is attached.
0156:             */
0157:            protected Context context = null;
0158:
0159:            /**
0160:             * The debugging detail level for this component.
0161:             */
0162:            protected int debug = 0;
0163:
0164:            /**
0165:             * Return the MessageDigest implementation to be used when
0166:             * creating session identifiers.
0167:             */
0168:            protected MessageDigest digest = null;
0169:
0170:            /**
0171:             * A String initialization parameter used to increase the entropy of
0172:             * the initialization of our random number generator.
0173:             */
0174:            protected String entropy = null;
0175:
0176:            /**
0177:             * Descriptive information about this implementation.
0178:             */
0179:            protected static final String info = "org.apache.catalina.authenticator.AuthenticatorBase/1.0";
0180:
0181:            /**
0182:             * The lifecycle event support for this component.
0183:             */
0184:            protected LifecycleSupport lifecycle = new LifecycleSupport(this );
0185:
0186:            /**
0187:             * A random number generator to use when generating session identifiers.
0188:             */
0189:            protected Random random = null;
0190:
0191:            /**
0192:             * The Java class name of the random number generator class to be used
0193:             * when generating session identifiers.
0194:             */
0195:            protected String randomClass = "java.security.SecureRandom";
0196:
0197:            /**
0198:             * The string manager for this package.
0199:             */
0200:            protected static final StringManager sm = StringManager
0201:                    .getManager(Constants.Package);
0202:
0203:            /**
0204:             * The SingleSignOn implementation in our request processing chain,
0205:             * if there is one.
0206:             */
0207:            protected SingleSignOn sso = null;
0208:
0209:            /**
0210:             * Has this component been started?
0211:             */
0212:            protected boolean started = false;
0213:
0214:            // ------------------------------------------------------------- Properties
0215:
0216:            /**
0217:             * Return the message digest algorithm for this Manager.
0218:             */
0219:            public String getAlgorithm() {
0220:
0221:                return (this .algorithm);
0222:
0223:            }
0224:
0225:            /**
0226:             * Set the message digest algorithm for this Manager.
0227:             *
0228:             * @param algorithm The new message digest algorithm
0229:             */
0230:            public void setAlgorithm(String algorithm) {
0231:
0232:                this .algorithm = algorithm;
0233:
0234:            }
0235:
0236:            /**
0237:             * Return the cache authenticated Principals flag.
0238:             */
0239:            public boolean getCache() {
0240:
0241:                return (this .cache);
0242:
0243:            }
0244:
0245:            /**
0246:             * Set the cache authenticated Principals flag.
0247:             *
0248:             * @param cache The new cache flag
0249:             */
0250:            public void setCache(boolean cache) {
0251:
0252:                this .cache = cache;
0253:
0254:            }
0255:
0256:            /**
0257:             * Return the Container to which this Valve is attached.
0258:             */
0259:            public Container getContainer() {
0260:
0261:                return (this .context);
0262:
0263:            }
0264:
0265:            /**
0266:             * Set the Container to which this Valve is attached.
0267:             *
0268:             * @param container The container to which we are attached
0269:             */
0270:            public void setContainer(Container container) {
0271:
0272:                if (!(container instanceof  Context))
0273:                    throw new IllegalArgumentException(sm
0274:                            .getString("authenticator.notContext"));
0275:
0276:                super .setContainer(container);
0277:                this .context = (Context) container;
0278:
0279:            }
0280:
0281:            /**
0282:             * Return the debugging detail level for this component.
0283:             */
0284:            public int getDebug() {
0285:
0286:                return (this .debug);
0287:
0288:            }
0289:
0290:            /**
0291:             * Set the debugging detail level for this component.
0292:             *
0293:             * @param debug The new debugging detail level
0294:             */
0295:            public void setDebug(int debug) {
0296:
0297:                this .debug = debug;
0298:
0299:            }
0300:
0301:            /**
0302:             * Return the entropy increaser value, or compute a semi-useful value
0303:             * if this String has not yet been set.
0304:             */
0305:            public String getEntropy() {
0306:
0307:                // Calculate a semi-useful value if this has not been set
0308:                if (this .entropy == null)
0309:                    setEntropy(this .toString());
0310:
0311:                return (this .entropy);
0312:
0313:            }
0314:
0315:            /**
0316:             * Set the entropy increaser value.
0317:             *
0318:             * @param entropy The new entropy increaser value
0319:             */
0320:            public void setEntropy(String entropy) {
0321:
0322:                this .entropy = entropy;
0323:
0324:            }
0325:
0326:            /**
0327:             * Return descriptive information about this Valve implementation.
0328:             */
0329:            public String getInfo() {
0330:
0331:                return (this .info);
0332:
0333:            }
0334:
0335:            /**
0336:             * Return the random number generator class name.
0337:             */
0338:            public String getRandomClass() {
0339:
0340:                return (this .randomClass);
0341:
0342:            }
0343:
0344:            /**
0345:             * Set the random number generator class name.
0346:             *
0347:             * @param randomClass The new random number generator class name
0348:             */
0349:            public void setRandomClass(String randomClass) {
0350:
0351:                this .randomClass = randomClass;
0352:
0353:            }
0354:
0355:            // --------------------------------------------------------- Public Methods
0356:
0357:            /**
0358:             * Enforce the security restrictions in the web application deployment
0359:             * descriptor of our associated Context.
0360:             *
0361:             * @param request Request to be processed
0362:             * @param response Response to be processed
0363:             * @param context The valve context used to invoke the next valve
0364:             *  in the current processing pipeline
0365:             *
0366:             * @exception IOException if an input/output error occurs
0367:             * @exception ServletException if thrown by a processing element
0368:             */
0369:            public void invoke(Request request, Response response,
0370:                    ValveContext context) throws IOException, ServletException {
0371:
0372:                // If this is not an HTTP request, do nothing
0373:                if (!(request instanceof  HttpRequest)
0374:                        || !(response instanceof  HttpResponse)) {
0375:                    context.invokeNext(request, response);
0376:                    return;
0377:                }
0378:                if (!(request.getRequest() instanceof  HttpServletRequest)
0379:                        || !(response.getResponse() instanceof  HttpServletResponse)) {
0380:                    context.invokeNext(request, response);
0381:                    return;
0382:                }
0383:                HttpRequest hrequest = (HttpRequest) request;
0384:                HttpResponse hresponse = (HttpResponse) response;
0385:                if (debug >= 1)
0386:                    log("Security checking request "
0387:                            + ((HttpServletRequest) request.getRequest())
0388:                                    .getMethod()
0389:                            + " "
0390:                            + ((HttpServletRequest) request.getRequest())
0391:                                    .getRequestURI());
0392:                LoginConfig config = this .context.getLoginConfig();
0393:
0394:                // Have we got a cached authenticated Principal to record?
0395:                if (cache) {
0396:                    Principal principal = ((HttpServletRequest) request
0397:                            .getRequest()).getUserPrincipal();
0398:                    if (principal == null) {
0399:                        Session session = getSession(hrequest);
0400:                        if (session != null) {
0401:                            principal = session.getPrincipal();
0402:                            if (principal != null) {
0403:                                if (debug >= 1)
0404:                                    log("We have cached auth type "
0405:                                            + session.getAuthType()
0406:                                            + " for principal "
0407:                                            + session.getPrincipal());
0408:                                hrequest.setAuthType(session.getAuthType());
0409:                                hrequest.setUserPrincipal(principal);
0410:                            }
0411:                        }
0412:                    }
0413:                }
0414:
0415:                // Special handling for form-based logins to deal with the case
0416:                // where the login form (and therefore the "j_security_check" URI
0417:                // to which it submits) might be outside the secured area
0418:                String contextPath = this .context.getPath();
0419:                String requestURI = hrequest.getDecodedRequestURI();
0420:                if (requestURI.startsWith(contextPath)
0421:                        && requestURI.endsWith(Constants.FORM_ACTION)) {
0422:                    if (!authenticate(hrequest, hresponse, config)) {
0423:                        if (debug >= 1)
0424:                            log(" Failed authenticate() test");
0425:                        return;
0426:                    }
0427:                }
0428:
0429:                // Is this request URI subject to a security constraint?
0430:                SecurityConstraint constraint = findConstraint(hrequest);
0431:                if ((constraint == null) /* &&
0432:                           (!Constants.FORM_METHOD.equals(config.getAuthMethod())) */) {
0433:                    if (debug >= 1)
0434:                        log(" Not subject to any constraint");
0435:                    context.invokeNext(request, response);
0436:                    return;
0437:                }
0438:                if ((debug >= 1) && (constraint != null))
0439:                    log(" Subject to constraint " + constraint);
0440:
0441:                // Make sure that constrained resources are not cached by web proxies
0442:                // or browsers as caching can provide a security hole
0443:                if (!(((HttpServletRequest) hrequest.getRequest()).isSecure())) {
0444:                    HttpServletResponse sresponse = (HttpServletResponse) response
0445:                            .getResponse();
0446:                    sresponse.setHeader("Pragma", "No-cache");
0447:                    sresponse.setHeader("Cache-Control", "no-cache");
0448:                    sresponse.setDateHeader("Expires", 1);
0449:                }
0450:
0451:                // Enforce any user data constraint for this security constraint
0452:                if (debug >= 1)
0453:                    log(" Calling checkUserData()");
0454:                if (!checkUserData(hrequest, hresponse, constraint)) {
0455:                    if (debug >= 1)
0456:                        log(" Failed checkUserData() test");
0457:                    // ASSERT: Authenticator already set the appropriate
0458:                    // HTTP status code, so we do not have to do anything special
0459:                    return;
0460:                }
0461:
0462:                // Authenticate based upon the specified login configuration
0463:                if (constraint.getAuthConstraint()) {
0464:                    if (debug >= 1)
0465:                        log(" Calling authenticate()");
0466:                    if (!authenticate(hrequest, hresponse, config)) {
0467:                        if (debug >= 1)
0468:                            log(" Failed authenticate() test");
0469:                        // ASSERT: Authenticator already set the appropriate
0470:                        // HTTP status code, so we do not have to do anything special
0471:                        return;
0472:                    }
0473:                }
0474:
0475:                // Perform access control based on the specified role(s)
0476:                if (constraint.getAuthConstraint()) {
0477:                    if (debug >= 1)
0478:                        log(" Calling accessControl()");
0479:                    if (!accessControl(hrequest, hresponse, constraint)) {
0480:                        if (debug >= 1)
0481:                            log(" Failed accessControl() test");
0482:                        // ASSERT: AccessControl method has already set the appropriate
0483:                        // HTTP status code, so we do not have to do anything special
0484:                        return;
0485:                    }
0486:                }
0487:
0488:                // Any and all specified constraints have been satisfied
0489:                if (debug >= 1)
0490:                    log(" Successfully passed all security constraints");
0491:                context.invokeNext(request, response);
0492:
0493:            }
0494:
0495:            // ------------------------------------------------------ Protected Methods
0496:
0497:            /**
0498:             * Perform access control based on the specified authorization constraint.
0499:             * Return <code>true</code> if this constraint is satisfied and processing
0500:             * should continue, or <code>false</code> otherwise.
0501:             *
0502:             * @param request Request we are processing
0503:             * @param response Response we are creating
0504:             * @param constraint Security constraint we are enforcing
0505:             *
0506:             * @exception IOException if an input/output error occurs
0507:             */
0508:            protected boolean accessControl(HttpRequest request,
0509:                    HttpResponse response, SecurityConstraint constraint)
0510:                    throws IOException {
0511:
0512:                if (constraint == null)
0513:                    return (true);
0514:
0515:                // Specifically allow access to the form login and form error pages
0516:                // and the "j_security_check" action
0517:                LoginConfig config = context.getLoginConfig();
0518:                if ((config != null)
0519:                        && (Constants.FORM_METHOD
0520:                                .equals(config.getAuthMethod()))) {
0521:                    String requestURI = request.getDecodedRequestURI();
0522:                    String loginPage = context.getPath()
0523:                            + config.getLoginPage();
0524:                    if (loginPage.equals(requestURI)) {
0525:                        if (debug >= 1)
0526:                            log(" Allow access to login page " + loginPage);
0527:                        return (true);
0528:                    }
0529:                    String errorPage = context.getPath()
0530:                            + config.getErrorPage();
0531:                    if (errorPage.equals(requestURI)) {
0532:                        if (debug >= 1)
0533:                            log(" Allow access to error page " + errorPage);
0534:                        return (true);
0535:                    }
0536:                    if (requestURI.endsWith(Constants.FORM_ACTION)) {
0537:                        if (debug >= 1)
0538:                            log(" Allow access to username/password submission");
0539:                        return (true);
0540:                    }
0541:                }
0542:
0543:                // Which user principal have we already authenticated?
0544:                Principal principal = ((HttpServletRequest) request
0545:                        .getRequest()).getUserPrincipal();
0546:                if (principal == null) {
0547:                    if (debug >= 2)
0548:                        log("  No user authenticated, cannot grant access");
0549:                    ((HttpServletResponse) response.getResponse()).sendError(
0550:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
0551:                            sm.getString("authenticator.notAuthenticated"));
0552:                    return (false);
0553:                }
0554:
0555:                // Check each role included in this constraint
0556:                Realm realm = context.getRealm();
0557:                String roles[] = constraint.findAuthRoles();
0558:                if (roles == null)
0559:                    roles = new String[0];
0560:
0561:                if (constraint.getAllRoles())
0562:                    return (true);
0563:                if ((roles.length == 0) && (constraint.getAuthConstraint())) {
0564:                    ((HttpServletResponse) response.getResponse()).sendError(
0565:                            HttpServletResponse.SC_FORBIDDEN, sm
0566:                                    .getString("authenticator.forbidden"));
0567:                    return (false); // No listed roles means no access at all
0568:                }
0569:                for (int i = 0; i < roles.length; i++) {
0570:                    if (realm.hasRole(principal, roles[i]))
0571:                        return (true);
0572:                }
0573:
0574:                // Return a "Forbidden" message denying access to this resource
0575:                ((HttpServletResponse) response.getResponse()).sendError(
0576:                        HttpServletResponse.SC_FORBIDDEN, sm
0577:                                .getString("authenticator.forbidden"));
0578:                return (false);
0579:
0580:            }
0581:
0582:            /**
0583:             * Associate the specified single sign on identifier with the
0584:             * specified Session.
0585:             *
0586:             * @param ssoId Single sign on identifier
0587:             * @param session Session to be associated
0588:             */
0589:            protected void associate(String ssoId, Session session) {
0590:
0591:                if (sso == null)
0592:                    return;
0593:                sso.associate(ssoId, session);
0594:
0595:            }
0596:
0597:            /**
0598:             * Authenticate the user making this request, based on the specified
0599:             * login configuration.  Return <code>true</code> if any specified
0600:             * constraint has been satisfied, or <code>false</code> if we have
0601:             * created a response challenge already.
0602:             *
0603:             * @param request Request we are processing
0604:             * @param response Response we are creating
0605:             * @param login Login configuration describing how authentication
0606:             *              should be performed
0607:             *
0608:             * @exception IOException if an input/output error occurs
0609:             */
0610:            protected abstract boolean authenticate(HttpRequest request,
0611:                    HttpResponse response, LoginConfig config)
0612:                    throws IOException;
0613:
0614:            /**
0615:             * Enforce any user data constraint required by the security constraint
0616:             * guarding this request URI.  Return <code>true</code> if this constraint
0617:             * was not violated and processing should continue, or <code>false</code>
0618:             * if we have created a response already.
0619:             *
0620:             * @param request Request we are processing
0621:             * @param response Response we are creating
0622:             * @param constraint Security constraint being checked
0623:             *
0624:             * @exception IOException if an input/output error occurs
0625:             */
0626:            protected boolean checkUserData(HttpRequest request,
0627:                    HttpResponse response, SecurityConstraint constraint)
0628:                    throws IOException {
0629:
0630:                // Is there a relevant user data constraint?
0631:                if (constraint == null) {
0632:                    if (debug >= 2)
0633:                        log("  No applicable security constraint defined");
0634:                    return (true);
0635:                }
0636:                String userConstraint = constraint.getUserConstraint();
0637:                if (userConstraint == null) {
0638:                    if (debug >= 2)
0639:                        log("  No applicable user data constraint defined");
0640:                    return (true);
0641:                }
0642:                if (userConstraint.equals(Constants.NONE_TRANSPORT)) {
0643:                    if (debug >= 2)
0644:                        log("  User data constraint has no restrictions");
0645:                    return (true);
0646:                }
0647:
0648:                // Validate the request against the user data constraint
0649:                if (request.getRequest().isSecure()) {
0650:                    if (debug >= 2)
0651:                        log("  User data constraint already satisfied");
0652:                    return (true);
0653:                }
0654:
0655:                // Initialize variables we need to determine the appropriate action
0656:                HttpServletRequest hrequest = (HttpServletRequest) request
0657:                        .getRequest();
0658:                HttpServletResponse hresponse = (HttpServletResponse) response
0659:                        .getResponse();
0660:                int redirectPort = request.getConnector().getRedirectPort();
0661:
0662:                // Is redirecting disabled?
0663:                if (redirectPort <= 0) {
0664:                    if (debug >= 2)
0665:                        log("  SSL redirect is disabled");
0666:                    hresponse.sendError(HttpServletResponse.SC_FORBIDDEN,
0667:                            hrequest.getRequestURI());
0668:                    return (false);
0669:                }
0670:
0671:                // Redirect to the corresponding SSL port
0672:                String protocol = "https";
0673:                String host = hrequest.getServerName();
0674:                StringBuffer file = new StringBuffer(hrequest.getRequestURI());
0675:                String requestedSessionId = hrequest.getRequestedSessionId();
0676:                if ((requestedSessionId != null)
0677:                        && hrequest.isRequestedSessionIdFromURL()) {
0678:                    file.append(";jsessionid=");
0679:                    file.append(requestedSessionId);
0680:                }
0681:                String queryString = hrequest.getQueryString();
0682:                if (queryString != null) {
0683:                    file.append('?');
0684:                    file.append(queryString);
0685:                }
0686:                URL url = null;
0687:                try {
0688:                    url = new URL(protocol, host, redirectPort, file.toString());
0689:                    if (debug >= 2)
0690:                        log("  Redirecting to " + url.toString());
0691:                    hresponse.sendRedirect(url.toString());
0692:                    return (false);
0693:                } catch (MalformedURLException e) {
0694:                    if (debug >= 2)
0695:                        log("  Cannot create new URL", e);
0696:                    hresponse.sendError(
0697:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
0698:                            hrequest.getRequestURI());
0699:                    return (false);
0700:                }
0701:
0702:            }
0703:
0704:            /**
0705:             * Return the SecurityConstraint configured to guard the request URI for
0706:             * this request, or <code>null</code> if there is no such constraint.
0707:             *
0708:             * @param request Request we are processing
0709:             */
0710:            protected SecurityConstraint findConstraint(HttpRequest request) {
0711:
0712:                // Are there any defined security constraints?
0713:                SecurityConstraint constraints[] = context.findConstraints();
0714:                if ((constraints == null) || (constraints.length == 0)) {
0715:                    if (debug >= 2)
0716:                        log("  No applicable constraints defined");
0717:                    return (null);
0718:                }
0719:
0720:                // Check each defined security constraint
0721:                HttpServletRequest hreq = (HttpServletRequest) request
0722:                        .getRequest();
0723:                String uri = request.getDecodedRequestURI();
0724:                String contextPath = hreq.getContextPath();
0725:                if (contextPath.length() > 0)
0726:                    uri = uri.substring(contextPath.length());
0727:                uri = RequestUtil.URLDecode(uri); // Before checking constraints
0728:                String method = hreq.getMethod();
0729:                for (int i = 0; i < constraints.length; i++) {
0730:                    if (debug >= 2)
0731:                        log("  Checking constraint '" + constraints[i]
0732:                                + "' against " + method + " " + uri + " --> "
0733:                                + constraints[i].included(uri, method));
0734:                    if (constraints[i].included(uri, method))
0735:                        return (constraints[i]);
0736:                }
0737:
0738:                // No applicable security constraint was found
0739:                if (debug >= 2)
0740:                    log("  No applicable constraint located");
0741:                return (null);
0742:
0743:            }
0744:
0745:            /**
0746:             * Generate and return a new session identifier for the cookie that
0747:             * identifies an SSO principal.
0748:             */
0749:            protected synchronized String generateSessionId() {
0750:
0751:                // Generate a byte array containing a session identifier
0752:                Random random = getRandom();
0753:                byte bytes[] = new byte[SESSION_ID_BYTES];
0754:                getRandom().nextBytes(bytes);
0755:                bytes = getDigest().digest(bytes);
0756:
0757:                // Render the result as a String of hexadecimal digits
0758:                StringBuffer result = new StringBuffer();
0759:                for (int i = 0; i < bytes.length; i++) {
0760:                    byte b1 = (byte) ((bytes[i] & 0xf0) >> 4);
0761:                    byte b2 = (byte) (bytes[i] & 0x0f);
0762:                    if (b1 < 10)
0763:                        result.append((char) ('0' + b1));
0764:                    else
0765:                        result.append((char) ('A' + (b1 - 10)));
0766:                    if (b2 < 10)
0767:                        result.append((char) ('0' + b2));
0768:                    else
0769:                        result.append((char) ('A' + (b2 - 10)));
0770:                }
0771:                return (result.toString());
0772:
0773:            }
0774:
0775:            /**
0776:             * Return the MessageDigest object to be used for calculating
0777:             * session identifiers.  If none has been created yet, initialize
0778:             * one the first time this method is called.
0779:             */
0780:            protected synchronized MessageDigest getDigest() {
0781:
0782:                if (this .digest == null) {
0783:                    try {
0784:                        this .digest = MessageDigest.getInstance(algorithm);
0785:                    } catch (NoSuchAlgorithmException e) {
0786:                        try {
0787:                            this .digest = MessageDigest
0788:                                    .getInstance(DEFAULT_ALGORITHM);
0789:                        } catch (NoSuchAlgorithmException f) {
0790:                            this .digest = null;
0791:                        }
0792:                    }
0793:                }
0794:
0795:                return (this .digest);
0796:
0797:            }
0798:
0799:            /**
0800:             * Return the random number generator instance we should use for
0801:             * generating session identifiers.  If there is no such generator
0802:             * currently defined, construct and seed a new one.
0803:             */
0804:            protected synchronized Random getRandom() {
0805:
0806:                if (this .random == null) {
0807:                    try {
0808:                        Class clazz = Class.forName(randomClass);
0809:                        this .random = (Random) clazz.newInstance();
0810:                        long seed = System.currentTimeMillis();
0811:                        char entropy[] = getEntropy().toCharArray();
0812:                        for (int i = 0; i < entropy.length; i++) {
0813:                            long update = ((byte) entropy[i]) << ((i % 8) * 8);
0814:                            seed ^= update;
0815:                        }
0816:                        this .random.setSeed(seed);
0817:                    } catch (Exception e) {
0818:                        this .random = new java.util.Random();
0819:                    }
0820:                }
0821:
0822:                return (this .random);
0823:
0824:            }
0825:
0826:            /**
0827:             * Return the internal Session that is associated with this HttpRequest,
0828:             * or <code>null</code> if there is no such Session.
0829:             *
0830:             * @param request The HttpRequest we are processing
0831:             */
0832:            protected Session getSession(HttpRequest request) {
0833:
0834:                return (getSession(request, false));
0835:
0836:            }
0837:
0838:            /**
0839:             * Return the internal Session that is associated with this HttpRequest,
0840:             * possibly creating a new one if necessary, or <code>null</code> if
0841:             * there is no such session and we did not create one.
0842:             *
0843:             * @param request The HttpRequest we are processing
0844:             * @param create Should we create a session if needed?
0845:             */
0846:            protected Session getSession(HttpRequest request, boolean create) {
0847:
0848:                HttpServletRequest hreq = (HttpServletRequest) request
0849:                        .getRequest();
0850:                HttpSession hses = hreq.getSession(create);
0851:                if (hses == null)
0852:                    return (null);
0853:                Manager manager = context.getManager();
0854:                if (manager == null)
0855:                    return (null);
0856:                else {
0857:                    try {
0858:                        return (manager.findSession(hses.getId()));
0859:                    } catch (IOException e) {
0860:                        return (null);
0861:                    }
0862:                }
0863:
0864:            }
0865:
0866:            /**
0867:             * Log a message on the Logger associated with our Container (if any).
0868:             *
0869:             * @param message Message to be logged
0870:             */
0871:            protected void log(String message) {
0872:
0873:                Logger logger = context.getLogger();
0874:                if (logger != null)
0875:                    logger.log("Authenticator[" + context.getPath() + "]: "
0876:                            + message);
0877:                else
0878:                    System.out.println("Authenticator[" + context.getPath()
0879:                            + "]: " + message);
0880:
0881:            }
0882:
0883:            /**
0884:             * Log a message on the Logger associated with our Container (if any).
0885:             *
0886:             * @param message Message to be logged
0887:             * @param throwable Associated exception
0888:             */
0889:            protected void log(String message, Throwable throwable) {
0890:
0891:                Logger logger = context.getLogger();
0892:                if (logger != null)
0893:                    logger.log("Authenticator[" + context.getPath() + "]: "
0894:                            + message, throwable);
0895:                else {
0896:                    System.out.println("Authenticator[" + context.getPath()
0897:                            + "]: " + message);
0898:                    throwable.printStackTrace(System.out);
0899:                }
0900:
0901:            }
0902:
0903:            /**
0904:             * Register an authenticated Principal and authentication type in our
0905:             * request, in the current session (if there is one), and with our
0906:             * SingleSignOn valve, if there is one.  Set the appropriate cookie
0907:             * to be returned.
0908:             *
0909:             * @param request The servlet request we are processing
0910:             * @param response The servlet response we are generating
0911:             * @param principal The authenticated Principal to be registered
0912:             * @param authType The authentication type to be registered
0913:             * @param username Username used to authenticate (if any)
0914:             * @param password Password used to authenticate (if any)
0915:             */
0916:            protected void register(HttpRequest request, HttpResponse response,
0917:                    Principal principal, String authType, String username,
0918:                    String password) {
0919:
0920:                if (debug >= 1)
0921:                    log("Authenticated '" + principal.getName()
0922:                            + "' with type '" + authType + "'");
0923:
0924:                // Cache the authentication information in our request
0925:                request.setAuthType(authType);
0926:                request.setUserPrincipal(principal);
0927:
0928:                // Cache the authentication information in our session, if any
0929:                if (cache) {
0930:                    Session session = getSession(request, false);
0931:                    if (session != null) {
0932:                        session.setAuthType(authType);
0933:                        session.setPrincipal(principal);
0934:                        if (username != null)
0935:                            session.setNote(Constants.SESS_USERNAME_NOTE,
0936:                                    username);
0937:                        else
0938:                            session.removeNote(Constants.SESS_USERNAME_NOTE);
0939:                        if (password != null)
0940:                            session.setNote(Constants.SESS_PASSWORD_NOTE,
0941:                                    password);
0942:                        else
0943:                            session.removeNote(Constants.SESS_PASSWORD_NOTE);
0944:                    }
0945:                }
0946:
0947:                // Construct a cookie to be returned to the client
0948:                if (sso == null)
0949:                    return;
0950:                HttpServletRequest hreq = (HttpServletRequest) request
0951:                        .getRequest();
0952:                HttpServletResponse hres = (HttpServletResponse) response
0953:                        .getResponse();
0954:                String value = generateSessionId();
0955:                Cookie cookie = new Cookie(Constants.SINGLE_SIGN_ON_COOKIE,
0956:                        value);
0957:                cookie.setMaxAge(-1);
0958:                cookie.setPath("/");
0959:                hres.addCookie(cookie);
0960:
0961:                // Register this principal with our SSO valve
0962:                sso.register(value, principal, authType, username, password);
0963:                request.setNote(Constants.REQ_SSOID_NOTE, value);
0964:
0965:            }
0966:
0967:            // ------------------------------------------------------ Lifecycle Methods
0968:
0969:            /**
0970:             * Add a lifecycle event listener to this component.
0971:             *
0972:             * @param listener The listener to add
0973:             */
0974:            public void addLifecycleListener(LifecycleListener listener) {
0975:
0976:                lifecycle.addLifecycleListener(listener);
0977:
0978:            }
0979:
0980:            /**
0981:             * Get the lifecycle listeners associated with this lifecycle. If this 
0982:             * Lifecycle has no listeners registered, a zero-length array is returned.
0983:             */
0984:            public LifecycleListener[] findLifecycleListeners() {
0985:
0986:                return lifecycle.findLifecycleListeners();
0987:
0988:            }
0989:
0990:            /**
0991:             * Remove a lifecycle event listener from this component.
0992:             *
0993:             * @param listener The listener to remove
0994:             */
0995:            public void removeLifecycleListener(LifecycleListener listener) {
0996:
0997:                lifecycle.removeLifecycleListener(listener);
0998:
0999:            }
1000:
1001:            /**
1002:             * Prepare for the beginning of active use of the public methods of this
1003:             * component.  This method should be called after <code>configure()</code>,
1004:             * and before any of the public methods of the component are utilized.
1005:             *
1006:             * @exception LifecycleException if this component detects a fatal error
1007:             *  that prevents this component from being used
1008:             */
1009:            public void start() throws LifecycleException {
1010:
1011:                // Validate and update our current component state
1012:                if (started)
1013:                    throw new LifecycleException(sm
1014:                            .getString("authenticator.alreadyStarted"));
1015:                lifecycle.fireLifecycleEvent(START_EVENT, null);
1016:                if ("org.apache.catalina.core.StandardContext".equals(context
1017:                        .getClass().getName())) {
1018:                    try {
1019:                        Class paramTypes[] = new Class[0];
1020:                        Object paramValues[] = new Object[0];
1021:                        Method method = context.getClass().getMethod(
1022:                                "getDebug", paramTypes);
1023:                        Integer result = (Integer) method.invoke(context,
1024:                                paramValues);
1025:                        setDebug(result.intValue());
1026:                    } catch (Exception e) {
1027:                        log("Exception getting debug value", e);
1028:                    }
1029:                }
1030:                started = true;
1031:
1032:                // Look up the SingleSignOn implementation in our request processing
1033:                // path, if there is one
1034:                Container parent = context.getParent();
1035:                while ((sso == null) && (parent != null)) {
1036:                    if (!(parent instanceof  Pipeline)) {
1037:                        parent = parent.getParent();
1038:                        continue;
1039:                    }
1040:                    Valve valves[] = ((Pipeline) parent).getValves();
1041:                    for (int i = 0; i < valves.length; i++) {
1042:                        if (valves[i] instanceof  SingleSignOn) {
1043:                            sso = (SingleSignOn) valves[i];
1044:                            break;
1045:                        }
1046:                    }
1047:                    if (sso == null)
1048:                        parent = parent.getParent();
1049:                }
1050:                if (debug >= 1) {
1051:                    if (sso != null)
1052:                        log("Found SingleSignOn Valve at " + sso);
1053:                    else
1054:                        log("No SingleSignOn Valve is present");
1055:                }
1056:
1057:            }
1058:
1059:            /**
1060:             * Gracefully terminate the active use of the public methods of this
1061:             * component.  This method should be the last one called on a given
1062:             * instance of this component.
1063:             *
1064:             * @exception LifecycleException if this component detects a fatal error
1065:             *  that needs to be reported
1066:             */
1067:            public void stop() throws LifecycleException {
1068:
1069:                // Validate and update our current component state
1070:                if (!started)
1071:                    throw new LifecycleException(sm
1072:                            .getString("authenticator.notStarted"));
1073:                lifecycle.fireLifecycleEvent(STOP_EVENT, null);
1074:                started = false;
1075:
1076:                sso = null;
1077:
1078:            }
1079:
1080:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.