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


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