Source Code Cross Referenced for AuthenticatorBase.java in  » Sevlet-Container » tomcat-catalina » 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 » Sevlet Container » tomcat catalina » org.apache.catalina.authenticator 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 1999-2001,2004 The Apache Software Foundation.
003:         * 
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         * 
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         * 
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.apache.catalina.authenticator;
018:
019:        import java.io.IOException;
020:        import java.lang.reflect.Method;
021:        import java.security.MessageDigest;
022:        import java.security.NoSuchAlgorithmException;
023:        import java.security.Principal;
024:        import java.text.SimpleDateFormat;
025:        import java.util.Date;
026:        import java.util.Locale;
027:        import java.util.Random;
028:
029:        import javax.servlet.ServletException;
030:        import javax.servlet.http.Cookie;
031:        import javax.servlet.http.HttpServletRequest;
032:        import javax.servlet.http.HttpServletResponse;
033:        import javax.servlet.http.HttpSession;
034:
035:        import org.apache.catalina.Authenticator;
036:        import org.apache.catalina.Container;
037:        import org.apache.catalina.Context;
038:        import org.apache.catalina.HttpRequest;
039:        import org.apache.catalina.HttpResponse;
040:        import org.apache.catalina.Lifecycle;
041:        import org.apache.catalina.LifecycleException;
042:        import org.apache.catalina.LifecycleListener;
043:        import org.apache.catalina.Logger;
044:        import org.apache.catalina.Manager;
045:        import org.apache.catalina.Pipeline;
046:        import org.apache.catalina.Realm;
047:        import org.apache.catalina.Request;
048:        import org.apache.catalina.Response;
049:        import org.apache.catalina.Session;
050:        import org.apache.catalina.Valve;
051:        import org.apache.catalina.ValveContext;
052:        import org.apache.catalina.deploy.LoginConfig;
053:        import org.apache.catalina.deploy.SecurityConstraint;
054:        import org.apache.catalina.util.DateTool;
055:        import org.apache.catalina.util.LifecycleSupport;
056:        import org.apache.catalina.util.StringManager;
057:        import org.apache.catalina.valves.ValveBase;
058:        import org.apache.commons.logging.Log;
059:        import org.apache.commons.logging.LogFactory;
060:
061:        /**
062:         * Basic implementation of the <b>Valve</b> interface that enforces the
063:         * <code>&lt;security-constraint&gt;</code> elements in the web application
064:         * deployment descriptor.  This functionality is implemented as a Valve
065:         * so that it can be ommitted in environments that do not require these
066:         * features.  Individual implementations of each supported authentication
067:         * method can subclass this base class as required.
068:         * <p>
069:         * <b>USAGE CONSTRAINT</b>:  When this class is utilized, the Context to
070:         * which it is attached (or a parent Container in a hierarchy) must have an
071:         * associated Realm that can be used for authenticating users and enumerating
072:         * the roles to which they have been assigned.
073:         * <p>
074:         * <b>USAGE CONSTRAINT</b>:  This Valve is only useful when processing HTTP
075:         * requests.  Requests of any other type will simply be passed through.
076:         *
077:         * @author Craig R. McClanahan
078:         * @version $Revision: 1.19 $ $Date: 2004/04/26 21:54:15 $
079:         */
080:
081:        public abstract class AuthenticatorBase extends ValveBase implements 
082:                Authenticator, Lifecycle {
083:            private static Log log = LogFactory.getLog(AuthenticatorBase.class);
084:
085:            // ----------------------------------------------------- Instance Variables
086:
087:            /**
088:             * The default message digest algorithm to use if we cannot use
089:             * the requested one.
090:             */
091:            protected static final String DEFAULT_ALGORITHM = "MD5";
092:
093:            /**
094:             * The number of random bytes to include when generating a
095:             * session identifier.
096:             */
097:            protected static final int SESSION_ID_BYTES = 16;
098:
099:            /**
100:             * The message digest algorithm to be used when generating session
101:             * identifiers.  This must be an algorithm supported by the
102:             * <code>java.security.MessageDigest</code> class on your platform.
103:             */
104:            protected String algorithm = DEFAULT_ALGORITHM;
105:
106:            /**
107:             * Should we cache authenticated Principals if the request is part of
108:             * an HTTP session?
109:             */
110:            protected boolean cache = true;
111:
112:            /**
113:             * The Context to which this Valve is attached.
114:             */
115:            protected Context context = null;
116:
117:            /**
118:             * The debugging detail level for this component.
119:             */
120:            protected int debug = 0;
121:
122:            /**
123:             * Return the MessageDigest implementation to be used when
124:             * creating session identifiers.
125:             */
126:            protected MessageDigest digest = null;
127:
128:            /**
129:             * A String initialization parameter used to increase the entropy of
130:             * the initialization of our random number generator.
131:             */
132:            protected String entropy = null;
133:
134:            /**
135:             * Descriptive information about this implementation.
136:             */
137:            protected static final String info = "org.apache.catalina.authenticator.AuthenticatorBase/1.0";
138:
139:            /**
140:             * Flag to determine if we disable proxy caching, or leave the issue
141:             * up to the webapp developer.
142:             */
143:            protected boolean disableProxyCaching = true;
144:
145:            /**
146:             * The lifecycle event support for this component.
147:             */
148:            protected LifecycleSupport lifecycle = new LifecycleSupport(this );
149:
150:            /**
151:             * A random number generator to use when generating session identifiers.
152:             */
153:            protected Random random = null;
154:
155:            /**
156:             * The Java class name of the random number generator class to be used
157:             * when generating session identifiers.
158:             */
159:            protected String randomClass = "java.security.SecureRandom";
160:
161:            /**
162:             * The string manager for this package.
163:             */
164:            protected static final StringManager sm = StringManager
165:                    .getManager(Constants.Package);
166:
167:            /**
168:             * The SingleSignOn implementation in our request processing chain,
169:             * if there is one.
170:             */
171:            protected SingleSignOn sso = null;
172:
173:            /**
174:             * Has this component been started?
175:             */
176:            protected boolean started = false;
177:
178:            /**
179:             * "Expires" header always set to Date(1), so generate once only
180:             */
181:            private static final String DATE_ONE = (new SimpleDateFormat(
182:                    DateTool.HTTP_RESPONSE_DATE_HEADER, Locale.US))
183:                    .format(new Date(1));
184:
185:            // ------------------------------------------------------------- Properties
186:
187:            /**
188:             * Return the message digest algorithm for this Manager.
189:             */
190:            public String getAlgorithm() {
191:
192:                return (this .algorithm);
193:
194:            }
195:
196:            /**
197:             * Set the message digest algorithm for this Manager.
198:             *
199:             * @param algorithm The new message digest algorithm
200:             */
201:            public void setAlgorithm(String algorithm) {
202:
203:                this .algorithm = algorithm;
204:
205:            }
206:
207:            /**
208:             * Return the cache authenticated Principals flag.
209:             */
210:            public boolean getCache() {
211:
212:                return (this .cache);
213:
214:            }
215:
216:            /**
217:             * Set the cache authenticated Principals flag.
218:             *
219:             * @param cache The new cache flag
220:             */
221:            public void setCache(boolean cache) {
222:
223:                this .cache = cache;
224:
225:            }
226:
227:            /**
228:             * Return the Container to which this Valve is attached.
229:             */
230:            public Container getContainer() {
231:
232:                return (this .context);
233:
234:            }
235:
236:            /**
237:             * Set the Container to which this Valve is attached.
238:             *
239:             * @param container The container to which we are attached
240:             */
241:            public void setContainer(Container container) {
242:
243:                if (!(container instanceof  Context))
244:                    throw new IllegalArgumentException(sm
245:                            .getString("authenticator.notContext"));
246:
247:                super .setContainer(container);
248:                this .context = (Context) container;
249:
250:            }
251:
252:            /**
253:             * Return the debugging detail level for this component.
254:             */
255:            public int getDebug() {
256:
257:                return (this .debug);
258:
259:            }
260:
261:            /**
262:             * Set the debugging detail level for this component.
263:             *
264:             * @param debug The new debugging detail level
265:             */
266:            public void setDebug(int debug) {
267:
268:                this .debug = debug;
269:
270:            }
271:
272:            /**
273:             * Return the entropy increaser value, or compute a semi-useful value
274:             * if this String has not yet been set.
275:             */
276:            public String getEntropy() {
277:
278:                // Calculate a semi-useful value if this has not been set
279:                if (this .entropy == null)
280:                    setEntropy(this .toString());
281:
282:                return (this .entropy);
283:
284:            }
285:
286:            /**
287:             * Set the entropy increaser value.
288:             *
289:             * @param entropy The new entropy increaser value
290:             */
291:            public void setEntropy(String entropy) {
292:
293:                this .entropy = entropy;
294:
295:            }
296:
297:            /**
298:             * Return descriptive information about this Valve implementation.
299:             */
300:            public String getInfo() {
301:
302:                return (info);
303:
304:            }
305:
306:            /**
307:             * Return the random number generator class name.
308:             */
309:            public String getRandomClass() {
310:
311:                return (this .randomClass);
312:
313:            }
314:
315:            /**
316:             * Set the random number generator class name.
317:             *
318:             * @param randomClass The new random number generator class name
319:             */
320:            public void setRandomClass(String randomClass) {
321:
322:                this .randomClass = randomClass;
323:
324:            }
325:
326:            /**
327:             * Return the flag that states if we add headers to disable caching by
328:             * proxies.
329:             */
330:            public boolean getDisableProxyCaching() {
331:                return disableProxyCaching;
332:            }
333:
334:            /**
335:             * Set the value of the flag that states if we add headers to disable
336:             * caching by proxies.
337:             * @param nocache <code>true</code> if we add headers to disable proxy 
338:             *              caching, <code>false</code> if we leave the headers alone.
339:             */
340:            public void setDisableProxyCaching(boolean nocache) {
341:                disableProxyCaching = nocache;
342:            }
343:
344:            // --------------------------------------------------------- Public Methods
345:
346:            /**
347:             * Enforce the security restrictions in the web application deployment
348:             * descriptor of our associated Context.
349:             *
350:             * @param request Request to be processed
351:             * @param response Response to be processed
352:             * @param context The valve context used to invoke the next valve
353:             *  in the current processing pipeline
354:             *
355:             * @exception IOException if an input/output error occurs
356:             * @exception ServletException if thrown by a processing element
357:             */
358:            public void invoke(Request request, Response response,
359:                    ValveContext context) throws IOException, ServletException {
360:
361:                // If this is not an HTTP request, do nothing
362:                if (!(request instanceof  HttpRequest)
363:                        || !(response instanceof  HttpResponse)) {
364:                    context.invokeNext(request, response);
365:                    return;
366:                }
367:                if (!(request.getRequest() instanceof  HttpServletRequest)
368:                        || !(response.getResponse() instanceof  HttpServletResponse)) {
369:                    context.invokeNext(request, response);
370:                    return;
371:                }
372:                HttpRequest hrequest = (HttpRequest) request;
373:                HttpResponse hresponse = (HttpResponse) response;
374:                if (log.isDebugEnabled())
375:                    log.debug("Security checking request "
376:                            + ((HttpServletRequest) request.getRequest())
377:                                    .getMethod()
378:                            + " "
379:                            + ((HttpServletRequest) request.getRequest())
380:                                    .getRequestURI());
381:                LoginConfig config = this .context.getLoginConfig();
382:
383:                // Have we got a cached authenticated Principal to record?
384:                if (cache) {
385:                    Principal principal = ((HttpServletRequest) request
386:                            .getRequest()).getUserPrincipal();
387:                    if (principal == null) {
388:                        Session session = getSession(hrequest);
389:                        if (session != null) {
390:                            principal = session.getPrincipal();
391:                            if (principal != null) {
392:                                if (log.isDebugEnabled())
393:                                    log.debug("We have cached auth type "
394:                                            + session.getAuthType()
395:                                            + " for principal "
396:                                            + session.getPrincipal());
397:                                hrequest.setAuthType(session.getAuthType());
398:                                hrequest.setUserPrincipal(principal);
399:                            }
400:                        }
401:                    }
402:                }
403:
404:                // Special handling for form-based logins to deal with the case
405:                // where the login form (and therefore the "j_security_check" URI
406:                // to which it submits) might be outside the secured area
407:                String contextPath = this .context.getPath();
408:                String requestURI = hrequest.getDecodedRequestURI();
409:                if (requestURI.startsWith(contextPath)
410:                        && requestURI.endsWith(Constants.FORM_ACTION)) {
411:                    if (!authenticate(hrequest, hresponse, config)) {
412:                        if (log.isDebugEnabled())
413:                            log.debug(" Failed authenticate() test ??"
414:                                    + requestURI);
415:                        return;
416:                    }
417:                }
418:
419:                Realm realm = this .context.getRealm();
420:                // Is this request URI subject to a security constraint?
421:                SecurityConstraint[] constraints = realm
422:                        .findSecurityConstraints(hrequest, this .context);
423:
424:                if ((constraints == null) /* &&
425:                           (!Constants.FORM_METHOD.equals(config.getAuthMethod())) */) {
426:                    if (log.isDebugEnabled())
427:                        log.debug(" Not subject to any constraint");
428:                    context.invokeNext(request, response);
429:                    return;
430:                }
431:
432:                // Make sure that constrained resources are not cached by web proxies
433:                // or browsers as caching can provide a security hole
434:                HttpServletRequest hsrequest = (HttpServletRequest) hrequest
435:                        .getRequest();
436:                if (disableProxyCaching &&
437:                // FIXME: Disabled for Mozilla FORM support over SSL 
438:                        // (improper caching issue)
439:                        //!hsrequest.isSecure() &&
440:                        !"POST".equalsIgnoreCase(hsrequest.getMethod())) {
441:                    HttpServletResponse sresponse = (HttpServletResponse) response
442:                            .getResponse();
443:                    sresponse.setHeader("Pragma", "No-cache");
444:                    sresponse.setHeader("Cache-Control", "no-cache");
445:                    sresponse.setHeader("Expires", DATE_ONE);
446:                }
447:
448:                int i;
449:                // Enforce any user data constraint for this security constraint
450:                if (log.isDebugEnabled()) {
451:                    log.debug(" Calling hasUserDataPermission()");
452:                }
453:                if (!realm.hasUserDataPermission(hrequest, hresponse,
454:                        constraints)) {
455:                    if (log.isDebugEnabled()) {
456:                        log.debug(" Failed hasUserDataPermission() test");
457:                    }
458:                    /*
459:                     * ASSERT: Authenticator already set the appropriate
460:                     * HTTP status code, so we do not have to do anything special
461:                     */
462:                    return;
463:                }
464:
465:                for (i = 0; i < constraints.length; i++) {
466:                    // Authenticate based upon the specified login configuration
467:                    if (constraints[i].getAuthConstraint()) {
468:                        if (log.isDebugEnabled()) {
469:                            log.debug(" Calling authenticate()");
470:                        }
471:                        if (!authenticate(hrequest, hresponse, config)) {
472:                            if (log.isDebugEnabled()) {
473:                                log.debug(" Failed authenticate() test");
474:                            }
475:                            /*
476:                             * ASSERT: Authenticator already set the appropriate
477:                             * HTTP status code, so we do not have to do anything
478:                             * special
479:                             */
480:                            return;
481:                        } else {
482:                            break;
483:                        }
484:                    }
485:                }
486:                if (log.isDebugEnabled()) {
487:                    log.debug(" Calling accessControl()");
488:                }
489:                if (!realm.hasResourcePermission(hrequest, hresponse,
490:                        constraints, this .context)) {
491:                    if (log.isDebugEnabled()) {
492:                        log.debug(" Failed accessControl() test");
493:                    }
494:                    /*
495:                     * ASSERT: AccessControl method has already set the
496:                     * appropriate HTTP status code, so we do not have to do
497:                     * anything special
498:                     */
499:                    return;
500:                }
501:
502:                // Any and all specified constraints have been satisfied
503:                if (log.isDebugEnabled()) {
504:                    log.debug(" Successfully passed all security constraints");
505:                }
506:                context.invokeNext(request, response);
507:
508:            }
509:
510:            // ------------------------------------------------------ Protected Methods
511:
512:            /**
513:             * Associate the specified single sign on identifier with the
514:             * specified Session.
515:             *
516:             * @param ssoId Single sign on identifier
517:             * @param session Session to be associated
518:             */
519:            protected void associate(String ssoId, Session session) {
520:
521:                if (sso == null)
522:                    return;
523:                sso.associate(ssoId, session);
524:
525:            }
526:
527:            /**
528:             * Authenticate the user making this request, based on the specified
529:             * login configuration.  Return <code>true</code> if any specified
530:             * constraint has been satisfied, or <code>false</code> if we have
531:             * created a response challenge already.
532:             *
533:             * @param request Request we are processing
534:             * @param response Response we are creating
535:             * @param config    Login configuration describing how authentication
536:             *              should be performed
537:             *
538:             * @exception IOException if an input/output error occurs
539:             */
540:            protected abstract boolean authenticate(HttpRequest request,
541:                    HttpResponse response, LoginConfig config)
542:                    throws IOException;
543:
544:            /**
545:             * Generate and return a new session identifier for the cookie that
546:             * identifies an SSO principal.
547:             */
548:            protected synchronized String generateSessionId() {
549:
550:                // Generate a byte array containing a session identifier
551:                byte bytes[] = new byte[SESSION_ID_BYTES];
552:                getRandom().nextBytes(bytes);
553:                bytes = getDigest().digest(bytes);
554:
555:                // Render the result as a String of hexadecimal digits
556:                StringBuffer result = new StringBuffer();
557:                for (int i = 0; i < bytes.length; i++) {
558:                    byte b1 = (byte) ((bytes[i] & 0xf0) >> 4);
559:                    byte b2 = (byte) (bytes[i] & 0x0f);
560:                    if (b1 < 10)
561:                        result.append((char) ('0' + b1));
562:                    else
563:                        result.append((char) ('A' + (b1 - 10)));
564:                    if (b2 < 10)
565:                        result.append((char) ('0' + b2));
566:                    else
567:                        result.append((char) ('A' + (b2 - 10)));
568:                }
569:                return (result.toString());
570:
571:            }
572:
573:            /**
574:             * Return the MessageDigest object to be used for calculating
575:             * session identifiers.  If none has been created yet, initialize
576:             * one the first time this method is called.
577:             */
578:            protected synchronized MessageDigest getDigest() {
579:
580:                if (this .digest == null) {
581:                    try {
582:                        this .digest = MessageDigest.getInstance(algorithm);
583:                    } catch (NoSuchAlgorithmException e) {
584:                        try {
585:                            this .digest = MessageDigest
586:                                    .getInstance(DEFAULT_ALGORITHM);
587:                        } catch (NoSuchAlgorithmException f) {
588:                            this .digest = null;
589:                        }
590:                    }
591:                }
592:
593:                return (this .digest);
594:
595:            }
596:
597:            /**
598:             * Return the random number generator instance we should use for
599:             * generating session identifiers.  If there is no such generator
600:             * currently defined, construct and seed a new one.
601:             */
602:            protected synchronized Random getRandom() {
603:
604:                if (this .random == null) {
605:                    try {
606:                        Class clazz = Class.forName(randomClass);
607:                        this .random = (Random) clazz.newInstance();
608:                        long seed = System.currentTimeMillis();
609:                        char entropy[] = getEntropy().toCharArray();
610:                        for (int i = 0; i < entropy.length; i++) {
611:                            long update = ((byte) entropy[i]) << ((i % 8) * 8);
612:                            seed ^= update;
613:                        }
614:                        this .random.setSeed(seed);
615:                    } catch (Exception e) {
616:                        this .random = new java.util.Random();
617:                    }
618:                }
619:
620:                return (this .random);
621:
622:            }
623:
624:            /**
625:             * Return the internal Session that is associated with this HttpRequest,
626:             * or <code>null</code> if there is no such Session.
627:             *
628:             * @param request The HttpRequest we are processing
629:             */
630:            protected Session getSession(HttpRequest request) {
631:
632:                return (getSession(request, false));
633:
634:            }
635:
636:            /**
637:             * Return the internal Session that is associated with this HttpRequest,
638:             * possibly creating a new one if necessary, or <code>null</code> if
639:             * there is no such session and we did not create one.
640:             *
641:             * @param request The HttpRequest we are processing
642:             * @param create Should we create a session if needed?
643:             */
644:            protected Session getSession(HttpRequest request, boolean create) {
645:
646:                HttpServletRequest hreq = (HttpServletRequest) request
647:                        .getRequest();
648:                HttpSession hses = hreq.getSession(create);
649:                if (hses == null)
650:                    return (null);
651:                Manager manager = context.getManager();
652:                if (manager == null)
653:                    return (null);
654:                else {
655:                    try {
656:                        return (manager.findSession(hses.getId()));
657:                    } catch (IOException e) {
658:                        return (null);
659:                    }
660:                }
661:
662:            }
663:
664:            /**
665:             * Log a message on the Logger associated with our Container (if any).
666:             *
667:             * @param message Message to be logged
668:             */
669:            protected void log(String message) {
670:
671:                Logger logger = context.getLogger();
672:                if (logger != null)
673:                    logger.log("Authenticator[" + context.getPath() + "]: "
674:                            + message);
675:                else
676:                    System.out.println("Authenticator[" + context.getPath()
677:                            + "]: " + message);
678:
679:            }
680:
681:            /**
682:             * Log a message on the Logger associated with our Container (if any).
683:             *
684:             * @param message Message to be logged
685:             * @param throwable Associated exception
686:             */
687:            protected void log(String message, Throwable throwable) {
688:
689:                Logger logger = context.getLogger();
690:                if (logger != null)
691:                    logger.log("Authenticator[" + context.getPath() + "]: "
692:                            + message, throwable);
693:                else {
694:                    System.out.println("Authenticator[" + context.getPath()
695:                            + "]: " + message);
696:                    throwable.printStackTrace(System.out);
697:                }
698:
699:            }
700:
701:            /**
702:             * Attempts reauthentication to the <code>Realm</code> using
703:             * the credentials included in argument <code>entry</code>.
704:             *
705:             * @param ssoId identifier of SingleSignOn session with which the
706:             *              caller is associated
707:             * @param request   the request that needs to be authenticated
708:             */
709:            protected boolean reauthenticateFromSSO(String ssoId,
710:                    HttpRequest request) {
711:
712:                if (sso == null || ssoId == null)
713:                    return false;
714:
715:                boolean reauthenticated = false;
716:
717:                Container parent = getContainer();
718:                if (parent != null) {
719:                    Realm realm = parent.getRealm();
720:                    if (realm != null) {
721:                        reauthenticated = sso.reauthenticate(ssoId, realm,
722:                                request);
723:                    }
724:                }
725:
726:                if (reauthenticated) {
727:                    associate(ssoId, getSession(request, true));
728:
729:                    if (log.isDebugEnabled()) {
730:                        HttpServletRequest hreq = (HttpServletRequest) request
731:                                .getRequest();
732:                        log.debug(" Reauthenticated cached principal '"
733:                                + hreq.getUserPrincipal().getName()
734:                                + "' with auth type '" + hreq.getAuthType()
735:                                + "'");
736:                    }
737:                }
738:
739:                return reauthenticated;
740:            }
741:
742:            /**
743:             * Register an authenticated Principal and authentication type in our
744:             * request, in the current session (if there is one), and with our
745:             * SingleSignOn valve, if there is one.  Set the appropriate cookie
746:             * to be returned.
747:             *
748:             * @param request The servlet request we are processing
749:             * @param response The servlet response we are generating
750:             * @param principal The authenticated Principal to be registered
751:             * @param authType The authentication type to be registered
752:             * @param username Username used to authenticate (if any)
753:             * @param password Password used to authenticate (if any)
754:             */
755:            protected void register(HttpRequest request, HttpResponse response,
756:                    Principal principal, String authType, String username,
757:                    String password) {
758:
759:                if (log.isDebugEnabled())
760:                    log.debug("Authenticated '" + principal.getName()
761:                            + "' with type '" + authType + "'");
762:
763:                // Cache the authentication information in our request
764:                request.setAuthType(authType);
765:                request.setUserPrincipal(principal);
766:
767:                Session session = getSession(request, false);
768:                // Cache the authentication information in our session, if any
769:                if (cache) {
770:                    if (session != null) {
771:                        session.setAuthType(authType);
772:                        session.setPrincipal(principal);
773:                        if (username != null)
774:                            session.setNote(Constants.SESS_USERNAME_NOTE,
775:                                    username);
776:                        else
777:                            session.removeNote(Constants.SESS_USERNAME_NOTE);
778:                        if (password != null)
779:                            session.setNote(Constants.SESS_PASSWORD_NOTE,
780:                                    password);
781:                        else
782:                            session.removeNote(Constants.SESS_PASSWORD_NOTE);
783:                    }
784:                }
785:
786:                // Construct a cookie to be returned to the client
787:                if (sso == null)
788:                    return;
789:
790:                // Only create a new SSO entry if the SSO did not already set a note
791:                // for an existing entry (as it would do with subsequent requests
792:                // for DIGEST and SSL authenticated contexts)
793:                String ssoId = (String) request
794:                        .getNote(Constants.REQ_SSOID_NOTE);
795:                if (ssoId == null) {
796:                    // Construct a cookie to be returned to the client
797:                    HttpServletResponse hres = (HttpServletResponse) response
798:                            .getResponse();
799:                    ssoId = generateSessionId();
800:                    Cookie cookie = new Cookie(Constants.SINGLE_SIGN_ON_COOKIE,
801:                            ssoId);
802:                    cookie.setMaxAge(-1);
803:                    cookie.setPath("/");
804:                    hres.addCookie(cookie);
805:
806:                    // Register this principal with our SSO valve
807:                    sso
808:                            .register(ssoId, principal, authType, username,
809:                                    password);
810:                    request.setNote(Constants.REQ_SSOID_NOTE, ssoId);
811:
812:                } else {
813:                    // Update the SSO session with the latest authentication data
814:                    sso.update(ssoId, principal, authType, username, password);
815:                }
816:
817:                // Fix for Bug 10040
818:                // Always associate a session with a new SSO reqistration.
819:                // SSO entries are only removed from the SSO registry map when
820:                // associated sessions are destroyed; if a new SSO entry is created
821:                // above for this request and the user never revisits the context, the
822:                // SSO entry will never be cleared if we don't associate the session
823:                if (session == null)
824:                    session = getSession(request, true);
825:                sso.associate(ssoId, session);
826:
827:            }
828:
829:            // ------------------------------------------------------ Lifecycle Methods
830:
831:            /**
832:             * Add a lifecycle event listener to this component.
833:             *
834:             * @param listener The listener to add
835:             */
836:            public void addLifecycleListener(LifecycleListener listener) {
837:
838:                lifecycle.addLifecycleListener(listener);
839:
840:            }
841:
842:            /**
843:             * Get the lifecycle listeners associated with this lifecycle. If this 
844:             * Lifecycle has no listeners registered, a zero-length array is returned.
845:             */
846:            public LifecycleListener[] findLifecycleListeners() {
847:
848:                return lifecycle.findLifecycleListeners();
849:
850:            }
851:
852:            /**
853:             * Remove a lifecycle event listener from this component.
854:             *
855:             * @param listener The listener to remove
856:             */
857:            public void removeLifecycleListener(LifecycleListener listener) {
858:
859:                lifecycle.removeLifecycleListener(listener);
860:
861:            }
862:
863:            /**
864:             * Prepare for the beginning of active use of the public methods of this
865:             * component.  This method should be called after <code>configure()</code>,
866:             * and before any of the public methods of the component are utilized.
867:             *
868:             * @exception LifecycleException if this component detects a fatal error
869:             *  that prevents this component from being used
870:             */
871:            public void start() throws LifecycleException {
872:
873:                // Validate and update our current component state
874:                if (started)
875:                    throw new LifecycleException(sm
876:                            .getString("authenticator.alreadyStarted"));
877:                lifecycle.fireLifecycleEvent(START_EVENT, null);
878:                if ("org.apache.catalina.core.StandardContext".equals(context
879:                        .getClass().getName())) {
880:                    try {
881:                        // XXX What is this ???
882:                        Class paramTypes[] = new Class[0];
883:                        Object paramValues[] = new Object[0];
884:                        Method method = context.getClass().getMethod(
885:                                "getDebug", paramTypes);
886:                        Integer result = (Integer) method.invoke(context,
887:                                paramValues);
888:                        setDebug(result.intValue());
889:                    } catch (Exception e) {
890:                        log.error("Exception getting debug value", e);
891:                    }
892:                }
893:                started = true;
894:
895:                // Look up the SingleSignOn implementation in our request processing
896:                // path, if there is one
897:                Container parent = context.getParent();
898:                while ((sso == null) && (parent != null)) {
899:                    if (!(parent instanceof  Pipeline)) {
900:                        parent = parent.getParent();
901:                        continue;
902:                    }
903:                    Valve valves[] = ((Pipeline) parent).getValves();
904:                    for (int i = 0; i < valves.length; i++) {
905:                        if (valves[i] instanceof  SingleSignOn) {
906:                            sso = (SingleSignOn) valves[i];
907:                            break;
908:                        }
909:                    }
910:                    if (sso == null)
911:                        parent = parent.getParent();
912:                }
913:                if (log.isDebugEnabled()) {
914:                    if (sso != null)
915:                        log.debug("Found SingleSignOn Valve at " + sso);
916:                    else
917:                        log.debug("No SingleSignOn Valve is present");
918:                }
919:
920:            }
921:
922:            /**
923:             * Gracefully terminate the active use of the public methods of this
924:             * component.  This method should be the last one called on a given
925:             * instance of this component.
926:             *
927:             * @exception LifecycleException if this component detects a fatal error
928:             *  that needs to be reported
929:             */
930:            public void stop() throws LifecycleException {
931:
932:                // Validate and update our current component state
933:                if (!started)
934:                    throw new LifecycleException(sm
935:                            .getString("authenticator.notStarted"));
936:                lifecycle.fireLifecycleEvent(STOP_EVENT, null);
937:                started = false;
938:
939:                sso = null;
940:
941:            }
942:
943:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.