55 * LoginModule. For example, one could |
55 * LoginModule. For example, one could |
56 * configure both a Kerberos LoginModule and a smart card |
56 * configure both a Kerberos LoginModule and a smart card |
57 * LoginModule under an application. |
57 * LoginModule under an application. |
58 * |
58 * |
59 * <p> A typical caller instantiates a LoginContext with |
59 * <p> A typical caller instantiates a LoginContext with |
60 * a <i>name</i> and a <code>CallbackHandler</code>. |
60 * a <i>name</i> and a {@code CallbackHandler}. |
61 * LoginContext uses the <i>name</i> as the index into a |
61 * LoginContext uses the <i>name</i> as the index into a |
62 * Configuration to determine which LoginModules should be used, |
62 * Configuration to determine which LoginModules should be used, |
63 * and which ones must succeed in order for the overall authentication to |
63 * and which ones must succeed in order for the overall authentication to |
64 * succeed. The <code>CallbackHandler</code> is passed to the underlying |
64 * succeed. The {@code CallbackHandler} is passed to the underlying |
65 * LoginModules so they may communicate and interact with users |
65 * LoginModules so they may communicate and interact with users |
66 * (prompting for a username and password via a graphical user interface, |
66 * (prompting for a username and password via a graphical user interface, |
67 * for example). |
67 * for example). |
68 * |
68 * |
69 * <p> Once the caller has instantiated a LoginContext, |
69 * <p> Once the caller has instantiated a LoginContext, |
70 * it invokes the <code>login</code> method to authenticate |
70 * it invokes the {@code login} method to authenticate |
71 * a <code>Subject</code>. The <code>login</code> method invokes |
71 * a {@code Subject}. The {@code login} method invokes |
72 * the configured modules to perform their respective types of authentication |
72 * the configured modules to perform their respective types of authentication |
73 * (username/password, smart card pin verification, etc.). |
73 * (username/password, smart card pin verification, etc.). |
74 * Note that the LoginModules will not attempt authentication retries nor |
74 * Note that the LoginModules will not attempt authentication retries nor |
75 * introduce delays if the authentication fails. |
75 * introduce delays if the authentication fails. |
76 * Such tasks belong to the LoginContext caller. |
76 * Such tasks belong to the LoginContext caller. |
77 * |
77 * |
78 * <p> If the <code>login</code> method returns without |
78 * <p> If the {@code login} method returns without |
79 * throwing an exception, then the overall authentication succeeded. |
79 * throwing an exception, then the overall authentication succeeded. |
80 * The caller can then retrieve |
80 * The caller can then retrieve |
81 * the newly authenticated Subject by invoking the |
81 * the newly authenticated Subject by invoking the |
82 * <code>getSubject</code> method. Principals and Credentials associated |
82 * {@code getSubject} method. Principals and Credentials associated |
83 * with the Subject may be retrieved by invoking the Subject's |
83 * with the Subject may be retrieved by invoking the Subject's |
84 * respective <code>getPrincipals</code>, <code>getPublicCredentials</code>, |
84 * respective {@code getPrincipals}, {@code getPublicCredentials}, |
85 * and <code>getPrivateCredentials</code> methods. |
85 * and {@code getPrivateCredentials} methods. |
86 * |
86 * |
87 * <p> To logout the Subject, the caller calls |
87 * <p> To logout the Subject, the caller calls |
88 * the <code>logout</code> method. As with the <code>login</code> |
88 * the {@code logout} method. As with the {@code login} |
89 * method, this <code>logout</code> method invokes the <code>logout</code> |
89 * method, this {@code logout} method invokes the {@code logout} |
90 * method for the configured modules. |
90 * method for the configured modules. |
91 * |
91 * |
92 * <p> A LoginContext should not be used to authenticate |
92 * <p> A LoginContext should not be used to authenticate |
93 * more than one Subject. A separate LoginContext |
93 * more than one Subject. A separate LoginContext |
94 * should be used to authenticate each different Subject. |
94 * should be used to authenticate each different Subject. |
95 * |
95 * |
96 * <p> The following documentation applies to all LoginContext constructors: |
96 * <p> The following documentation applies to all LoginContext constructors: |
97 * <ol> |
97 * <ol> |
98 * |
98 * |
99 * <li> <code>Subject</code> |
99 * <li> {@code Subject} |
100 * <ul> |
100 * <ul> |
101 * <li> If the constructor has a Subject |
101 * <li> If the constructor has a Subject |
102 * input parameter, the LoginContext uses the caller-specified |
102 * input parameter, the LoginContext uses the caller-specified |
103 * Subject object. |
103 * Subject object. |
104 * <p> |
104 * <p> |
105 * <li> If the caller specifies a <code>null</code> Subject |
105 * <li> If the caller specifies a {@code null} Subject |
106 * and a <code>null</code> value is permitted, |
106 * and a {@code null} value is permitted, |
107 * the LoginContext instantiates a new Subject. |
107 * the LoginContext instantiates a new Subject. |
108 * <p> |
108 * <p> |
109 * <li> If the constructor does <b>not</b> have a Subject |
109 * <li> If the constructor does <b>not</b> have a Subject |
110 * input parameter, the LoginContext instantiates a new Subject. |
110 * input parameter, the LoginContext instantiates a new Subject. |
111 * <p> |
111 * <p> |
112 * </ul> |
112 * </ul> |
113 * |
113 * |
114 * <li> <code>Configuration</code> |
114 * <li> {@code Configuration} |
115 * <ul> |
115 * <ul> |
116 * <li> If the constructor has a Configuration |
116 * <li> If the constructor has a Configuration |
117 * input parameter and the caller specifies a non-null Configuration, |
117 * input parameter and the caller specifies a non-null Configuration, |
118 * the LoginContext uses the caller-specified Configuration. |
118 * the LoginContext uses the caller-specified Configuration. |
119 * <p> |
119 * <p> |
120 * If the constructor does <b>not</b> have a Configuration |
120 * If the constructor does <b>not</b> have a Configuration |
121 * input parameter, or if the caller specifies a <code>null</code> |
121 * input parameter, or if the caller specifies a {@code null} |
122 * Configuration object, the constructor uses the following call to |
122 * Configuration object, the constructor uses the following call to |
123 * get the installed Configuration: |
123 * get the installed Configuration: |
124 * <pre> |
124 * <pre> |
125 * config = Configuration.getConfiguration(); |
125 * config = Configuration.getConfiguration(); |
126 * </pre> |
126 * </pre> |
127 * For both cases, |
127 * For both cases, |
128 * the <i>name</i> argument given to the constructor is passed to the |
128 * the <i>name</i> argument given to the constructor is passed to the |
129 * <code>Configuration.getAppConfigurationEntry</code> method. |
129 * {@code Configuration.getAppConfigurationEntry} method. |
130 * If the Configuration has no entries for the specified <i>name</i>, |
130 * If the Configuration has no entries for the specified <i>name</i>, |
131 * then the <code>LoginContext</code> calls |
131 * then the {@code LoginContext} calls |
132 * <code>getAppConfigurationEntry</code> with the name, "<i>other</i>" |
132 * {@code getAppConfigurationEntry} with the name, "<i>other</i>" |
133 * (the default entry name). If there is no entry for "<i>other</i>", |
133 * (the default entry name). If there is no entry for "<i>other</i>", |
134 * then a <code>LoginException</code> is thrown. |
134 * then a {@code LoginException} is thrown. |
135 * <p> |
135 * <p> |
136 * <li> When LoginContext uses the installed Configuration, the caller |
136 * <li> When LoginContext uses the installed Configuration, the caller |
137 * requires the createLoginContext.<em>name</em> and possibly |
137 * requires the createLoginContext.<em>name</em> and possibly |
138 * createLoginContext.other AuthPermissions. Furthermore, the |
138 * createLoginContext.other AuthPermissions. Furthermore, the |
139 * LoginContext will invoke configured modules from within an |
139 * LoginContext will invoke configured modules from within an |
140 * <code>AccessController.doPrivileged</code> call so that modules that |
140 * {@code AccessController.doPrivileged} call so that modules that |
141 * perform security-sensitive tasks (such as connecting to remote hosts, |
141 * perform security-sensitive tasks (such as connecting to remote hosts, |
142 * and updating the Subject) will require the respective permissions, but |
142 * and updating the Subject) will require the respective permissions, but |
143 * the callers of the LoginContext will not require those permissions. |
143 * the callers of the LoginContext will not require those permissions. |
144 * <p> |
144 * <p> |
145 * <li> When LoginContext uses a caller-specified Configuration, the caller |
145 * <li> When LoginContext uses a caller-specified Configuration, the caller |
146 * does not require any createLoginContext AuthPermission. The LoginContext |
146 * does not require any createLoginContext AuthPermission. The LoginContext |
147 * saves the <code>AccessControlContext</code> for the caller, |
147 * saves the {@code AccessControlContext} for the caller, |
148 * and invokes the configured modules from within an |
148 * and invokes the configured modules from within an |
149 * <tt>AccessController.doPrivileged</tt> call constrained by that context. |
149 * {@code AccessController.doPrivileged} call constrained by that context. |
150 * This means the caller context (stored when the LoginContext was created) |
150 * This means the caller context (stored when the LoginContext was created) |
151 * must have sufficient permissions to perform any security-sensitive tasks |
151 * must have sufficient permissions to perform any security-sensitive tasks |
152 * that the modules may perform. |
152 * that the modules may perform. |
153 * <p> |
153 * <p> |
154 * </ul> |
154 * </ul> |
155 * |
155 * |
156 * <li> <code>CallbackHandler</code> |
156 * <li> {@code CallbackHandler} |
157 * <ul> |
157 * <ul> |
158 * <li> If the constructor has a CallbackHandler |
158 * <li> If the constructor has a CallbackHandler |
159 * input parameter, the LoginContext uses the caller-specified |
159 * input parameter, the LoginContext uses the caller-specified |
160 * CallbackHandler object. |
160 * CallbackHandler object. |
161 * <p> |
161 * <p> |
162 * <li> If the constructor does <b>not</b> have a CallbackHandler |
162 * <li> If the constructor does <b>not</b> have a CallbackHandler |
163 * input parameter, or if the caller specifies a <code>null</code> |
163 * input parameter, or if the caller specifies a {@code null} |
164 * CallbackHandler object (and a <code>null</code> value is permitted), |
164 * CallbackHandler object (and a {@code null} value is permitted), |
165 * the LoginContext queries the |
165 * the LoginContext queries the |
166 * {@code auth.login.defaultCallbackHandler} security property for the |
166 * {@code auth.login.defaultCallbackHandler} security property for the |
167 * fully qualified class name of a default handler |
167 * fully qualified class name of a default handler |
168 * implementation. If the security property is not set, |
168 * implementation. If the security property is not set, |
169 * then the underlying modules will not have a |
169 * then the underlying modules will not have a |
415 (java.security.AccessController.getContext(), |
415 (java.security.AccessController.getContext(), |
416 callbackHandler); |
416 callbackHandler); |
417 } |
417 } |
418 |
418 |
419 /** |
419 /** |
420 * Instantiate a new <code>LoginContext</code> object with a name, |
420 * Instantiate a new {@code LoginContext} object with a name, |
421 * a <code>Subject</code> to be authenticated, and a |
421 * a {@code Subject} to be authenticated, and a |
422 * <code>CallbackHandler</code> object. |
422 * {@code CallbackHandler} object. |
423 * |
423 * |
424 * <p> |
424 * <p> |
425 * |
425 * |
426 * @param name the name used as the index into the |
426 * @param name the name used as the index into the |
427 * <code>Configuration</code>. <p> |
427 * {@code Configuration}. <p> |
428 * |
428 * |
429 * @param subject the <code>Subject</code> to authenticate. <p> |
429 * @param subject the {@code Subject} to authenticate. <p> |
430 * |
430 * |
431 * @param callbackHandler the <code>CallbackHandler</code> object used by |
431 * @param callbackHandler the {@code CallbackHandler} object used by |
432 * LoginModules to communicate with the user. |
432 * LoginModules to communicate with the user. |
433 * |
433 * |
434 * @exception LoginException if the caller-specified <code>name</code> |
434 * @exception LoginException if the caller-specified {@code name} |
435 * does not appear in the <code>Configuration</code> |
435 * does not appear in the {@code Configuration} |
436 * and there is no <code>Configuration</code> entry |
436 * and there is no {@code Configuration} entry |
437 * for "<i>other</i>", or if the caller-specified |
437 * for "<i>other</i>", or if the caller-specified |
438 * <code>subject</code> is <code>null</code>, |
438 * {@code subject} is {@code null}, |
439 * or if the caller-specified |
439 * or if the caller-specified |
440 * <code>callbackHandler</code> is <code>null</code>. |
440 * {@code callbackHandler} is {@code null}. |
441 * <p> |
441 * <p> |
442 * @exception SecurityException if a SecurityManager is set and |
442 * @exception SecurityException if a SecurityManager is set and |
443 * the caller does not have |
443 * the caller does not have |
444 * AuthPermission("createLoginContext.<i>name</i>"), |
444 * AuthPermission("createLoginContext.<i>name</i>"), |
445 * or if a configuration entry for <i>name</i> does not exist and |
445 * or if a configuration entry for <i>name</i> does not exist and |
456 (java.security.AccessController.getContext(), |
456 (java.security.AccessController.getContext(), |
457 callbackHandler); |
457 callbackHandler); |
458 } |
458 } |
459 |
459 |
460 /** |
460 /** |
461 * Instantiate a new <code>LoginContext</code> object with a name, |
461 * Instantiate a new {@code LoginContext} object with a name, |
462 * a <code>Subject</code> to be authenticated, |
462 * a {@code Subject} to be authenticated, |
463 * a <code>CallbackHandler</code> object, and a login |
463 * a {@code CallbackHandler} object, and a login |
464 * <code>Configuration</code>. |
464 * {@code Configuration}. |
465 * |
465 * |
466 * <p> |
466 * <p> |
467 * |
467 * |
468 * @param name the name used as the index into the caller-specified |
468 * @param name the name used as the index into the caller-specified |
469 * <code>Configuration</code>. <p> |
469 * {@code Configuration}. <p> |
470 * |
470 * |
471 * @param subject the <code>Subject</code> to authenticate, |
471 * @param subject the {@code Subject} to authenticate, |
472 * or <code>null</code>. <p> |
472 * or {@code null}. <p> |
473 * |
473 * |
474 * @param callbackHandler the <code>CallbackHandler</code> object used by |
474 * @param callbackHandler the {@code CallbackHandler} object used by |
475 * LoginModules to communicate with the user, or <code>null</code>. |
475 * LoginModules to communicate with the user, or {@code null}. |
476 * <p> |
476 * <p> |
477 * |
477 * |
478 * @param config the <code>Configuration</code> that lists the |
478 * @param config the {@code Configuration} that lists the |
479 * login modules to be called to perform the authentication, |
479 * login modules to be called to perform the authentication, |
480 * or <code>null</code>. |
480 * or {@code null}. |
481 * |
481 * |
482 * @exception LoginException if the caller-specified <code>name</code> |
482 * @exception LoginException if the caller-specified {@code name} |
483 * does not appear in the <code>Configuration</code> |
483 * does not appear in the {@code Configuration} |
484 * and there is no <code>Configuration</code> entry |
484 * and there is no {@code Configuration} entry |
485 * for "<i>other</i>". |
485 * for "<i>other</i>". |
486 * <p> |
486 * <p> |
487 * @exception SecurityException if a SecurityManager is set, |
487 * @exception SecurityException if a SecurityManager is set, |
488 * <i>config</i> is <code>null</code>, |
488 * <i>config</i> is {@code null}, |
489 * and either the caller does not have |
489 * and either the caller does not have |
490 * AuthPermission("createLoginContext.<i>name</i>"), |
490 * AuthPermission("createLoginContext.<i>name</i>"), |
491 * or if a configuration entry for <i>name</i> does not exist and |
491 * or if a configuration entry for <i>name</i> does not exist and |
492 * the caller does not additionally have |
492 * the caller does not additionally have |
493 * AuthPermission("createLoginContext.other") |
493 * AuthPermission("createLoginContext.other") |
520 } |
520 } |
521 |
521 |
522 /** |
522 /** |
523 * Perform the authentication. |
523 * Perform the authentication. |
524 * |
524 * |
525 * <p> This method invokes the <code>login</code> method for each |
525 * <p> This method invokes the {@code login} method for each |
526 * LoginModule configured for the <i>name</i> specified to the |
526 * LoginModule configured for the <i>name</i> specified to the |
527 * <code>LoginContext</code> constructor, as determined by the login |
527 * {@code LoginContext} constructor, as determined by the login |
528 * <code>Configuration</code>. Each <code>LoginModule</code> |
528 * {@code Configuration}. Each {@code LoginModule} |
529 * then performs its respective type of authentication |
529 * then performs its respective type of authentication |
530 * (username/password, smart card pin verification, etc.). |
530 * (username/password, smart card pin verification, etc.). |
531 * |
531 * |
532 * <p> This method completes a 2-phase authentication process by |
532 * <p> This method completes a 2-phase authentication process by |
533 * calling each configured LoginModule's <code>commit</code> method |
533 * calling each configured LoginModule's {@code commit} method |
534 * if the overall authentication succeeded (the relevant REQUIRED, |
534 * if the overall authentication succeeded (the relevant REQUIRED, |
535 * REQUISITE, SUFFICIENT, and OPTIONAL LoginModules succeeded), |
535 * REQUISITE, SUFFICIENT, and OPTIONAL LoginModules succeeded), |
536 * or by calling each configured LoginModule's <code>abort</code> method |
536 * or by calling each configured LoginModule's {@code abort} method |
537 * if the overall authentication failed. If authentication succeeded, |
537 * if the overall authentication failed. If authentication succeeded, |
538 * each successful LoginModule's <code>commit</code> method associates |
538 * each successful LoginModule's {@code commit} method associates |
539 * the relevant Principals and Credentials with the <code>Subject</code>. |
539 * the relevant Principals and Credentials with the {@code Subject}. |
540 * If authentication failed, each LoginModule's <code>abort</code> method |
540 * If authentication failed, each LoginModule's {@code abort} method |
541 * removes/destroys any previously stored state. |
541 * removes/destroys any previously stored state. |
542 * |
542 * |
543 * <p> If the <code>commit</code> phase of the authentication process |
543 * <p> If the {@code commit} phase of the authentication process |
544 * fails, then the overall authentication fails and this method |
544 * fails, then the overall authentication fails and this method |
545 * invokes the <code>abort</code> method for each configured |
545 * invokes the {@code abort} method for each configured |
546 * <code>LoginModule</code>. |
546 * {@code LoginModule}. |
547 * |
547 * |
548 * <p> If the <code>abort</code> phase |
548 * <p> If the {@code abort} phase |
549 * fails for any reason, then this method propagates the |
549 * fails for any reason, then this method propagates the |
550 * original exception thrown either during the <code>login</code> phase |
550 * original exception thrown either during the {@code login} phase |
551 * or the <code>commit</code> phase. In either case, the overall |
551 * or the {@code commit} phase. In either case, the overall |
552 * authentication fails. |
552 * authentication fails. |
553 * |
553 * |
554 * <p> In the case where multiple LoginModules fail, |
554 * <p> In the case where multiple LoginModules fail, |
555 * this method propagates the exception raised by the first |
555 * this method propagates the exception raised by the first |
556 * <code>LoginModule</code> which failed. |
556 * {@code LoginModule} which failed. |
557 * |
557 * |
558 * <p> Note that if this method enters the <code>abort</code> phase |
558 * <p> Note that if this method enters the {@code abort} phase |
559 * (either the <code>login</code> or <code>commit</code> phase failed), |
559 * (either the {@code login} or {@code commit} phase failed), |
560 * this method invokes all LoginModules configured for the |
560 * this method invokes all LoginModules configured for the |
561 * application regardless of their respective <code>Configuration</code> |
561 * application regardless of their respective {@code Configuration} |
562 * flag parameters. Essentially this means that <code>Requisite</code> |
562 * flag parameters. Essentially this means that {@code Requisite} |
563 * and <code>Sufficient</code> semantics are ignored during the |
563 * and {@code Sufficient} semantics are ignored during the |
564 * <code>abort</code> phase. This guarantees that proper cleanup |
564 * {@code abort} phase. This guarantees that proper cleanup |
565 * and state restoration can take place. |
565 * and state restoration can take place. |
566 * |
566 * |
567 * <p> |
567 * <p> |
568 * |
568 * |
569 * @exception LoginException if the authentication fails. |
569 * @exception LoginException if the authentication fails. |