KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > security > auth > login > ClientPasswordLoginModule


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.security.auth.login;
24
25 import java.util.*;
26 import javax.security.auth.*;
27 import javax.security.auth.callback.*;
28 import javax.security.auth.login.*;
29 import javax.security.auth.spi.*;
30 import com.sun.enterprise.security.auth.login.PasswordCredential;
31 import com.sun.enterprise.deployment.PrincipalImpl;
32 import com.sun.enterprise.util.LocalStringManagerImpl;
33 import java.util.logging.*;
34 import com.sun.logging.*;
35
36
37 /**
38  * <p> This sample LoginModule authenticates users with a password.
39  *
40  * <p> If testUser successfully authenticates itself,
41  * a <code>PrincipalImpl</code> with the testUser's username
42  * is added to the Subject.
43  *
44  * @author Harpreet Singh (harpreet.singh@sun.com)
45  */

46
47 public class ClientPasswordLoginModule implements LoginModule {
48
49     private static Logger _logger=null;
50     static {
51         _logger=LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
52     }
53
54     private static final String JavaDoc DEFAULT_REALMNAME = "default";
55     private static LocalStringManagerImpl localStrings =
56     new LocalStringManagerImpl(ClientPasswordLoginModule.class);
57     // initial state
58
private Subject subject;
59     private CallbackHandler callbackHandler;
60     private Map sharedState;
61     private Map options;
62
63     // the authentication status
64
private boolean succeeded = false;
65     private boolean commitSucceeded = false;
66
67     // username and password
68
private String JavaDoc username;
69     private char[] password;
70     
71     // testUser's PrincipalImpl
72
private PrincipalImpl userPrincipal;
73     public static String JavaDoc LOGIN_NAME = "j2eelogin.name";
74     public static String JavaDoc LOGIN_PASSWORD = "j2eelogin.password";
75
76
77     /**
78      * Initialize this <code>LoginModule</code>.
79      *
80      * <p>
81      *
82      * @param subject the <code>Subject</code> to be authenticated. <p>
83      *
84      * @param callbackHandler a <code>CallbackHandler</code> for communicating
85      * with the end user (prompting for usernames and
86      * passwords, for example). <p>
87      *
88      * @param sharedState shared <code>LoginModule</code> state. <p>
89      *
90      * @param options options specified in the login
91      * <code>Configuration</code> for this particular
92      * <code>LoginModule</code>.
93      */

94     public void initialize(Subject subject, CallbackHandler callbackHandler,
95             Map sharedState, Map options) {
96  
97     this.subject = subject;
98     this.callbackHandler = callbackHandler;
99     this.sharedState = sharedState;
100     this.options = options;
101
102     }
103
104     /**
105      * Authenticate the user by prompting for a username and password.
106      *
107      * <p>
108      *
109      * @return true in all cases since this <code>LoginModule</code>
110      * should not be ignored.
111      *
112      * @exception FailedLoginException if the authentication fails. <p>
113      *
114      * @exception LoginException if this <code>LoginModule</code>
115      * is unable to perform the authentication.
116      */

117     public boolean login() throws LoginException {
118
119     // prompt for a username and password
120
if (callbackHandler == null){
121         String JavaDoc failure = localStrings.getLocalString("login.nocallback","Error: no CallbackHandler available to garner authentication information from the user");
122         throw new LoginException(failure);
123     }
124     String JavaDoc uname = System.getProperty (LOGIN_NAME);
125         String JavaDoc pswd;
126     if (uname != null) {
127         username = new String JavaDoc (uname);
128         pswd = System.getProperty (LOGIN_PASSWORD);
129         char[] dest;
130         if (pswd == null){
131         dest = new char[0];
132         password = new char[0];
133         } else {
134         int length = pswd.length();
135         dest = new char[length];
136         pswd.getChars(0, length, dest, 0 );
137         password = new char[length];
138         }
139         System.arraycopy (dest, 0, password, 0, dest.length);
140     } else{
141         Callback[] callbacks = new Callback[2];
142         callbacks[0] = new NameCallback(localStrings.getLocalString("login.username", "ClientPasswordModule username: "));
143         callbacks[1] = new PasswordCallback(localStrings.getLocalString("login.password", "ClientPasswordModule password: "), false);
144         
145         try {
146         callbackHandler.handle(callbacks);
147         username = ((NameCallback)callbacks[0]).getName();
148         if(username == null){
149             String JavaDoc fail = localStrings.getLocalString("login.nousername", "No user specified");
150             throw new LoginException(fail);
151         }
152         char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword();
153         if (tmpPassword == null) {
154             // treat a NULL password as an empty password
155
tmpPassword = new char[0];
156         }
157         password = new char[tmpPassword.length];
158         System.arraycopy(tmpPassword, 0,
159                  password, 0, tmpPassword.length);
160         ((PasswordCallback)callbacks[1]).clearPassword();
161         
162         } catch (java.io.IOException JavaDoc ioe) {
163         throw new LoginException(ioe.toString());
164         } catch (UnsupportedCallbackException uce) {
165         String JavaDoc nocallback = localStrings.getLocalString("login.callback","Error: Callback not available to garner authentication information from user(CallbackName):" );
166         throw new LoginException(nocallback +
167                      uce.getCallback().toString());
168         }
169     }
170
171     // by default - the client side login module will always say
172
// that the login successful. The actual login will take place
173
// on the server side.
174

175         _logger.log(Level.FINEST,"\t\t[ClientPasswordLoginModule] " +
176                     "authentication succeeded");
177     succeeded = true;
178     return true;
179     }
180
181     
182     /**
183      * <p> This method is called if the LoginContext's
184      * overall authentication succeeded
185      * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
186      * succeeded).
187      *
188      * <p> If this LoginModule's own authentication attempt
189      * succeeded (checked by retrieving the private state saved by the
190      * <code>login</code> method), then this method associates a
191      * <code>PrincipalImpl</code>
192      * with the <code>Subject</code> located in the
193      * <code>LoginModule</code>. If this LoginModule's own
194      * authentication attempted failed, then this method removes
195      * any state that was originally saved.
196      *
197      * <p>
198      *
199      * @exception LoginException if the commit fails.
200      *
201      * @return true if this LoginModule's own login and commit
202      * attempts succeeded, or false otherwise.
203      */

204     public boolean commit() throws LoginException {
205     if (succeeded == false) {
206         return false;
207     } else {
208         // add a Principal (authenticated identity)
209
// to the Subject
210

211         // assume the user we authenticated is the PrincipalImpl
212
userPrincipal = new PrincipalImpl(username);
213         if (!subject.getPrincipals().contains(userPrincipal)){
214         subject.getPrincipals().add(userPrincipal);
215             }
216             _logger.log(Level.FINE,"\t\t[ClientPasswordLoginModule] " +
217                         "added PrincipalImpl to Subject");
218             
219         String JavaDoc realm = DEFAULT_REALMNAME;
220
221         PasswordCredential pc =
222         new PasswordCredential(username, new String JavaDoc(password), realm);
223         if(!subject.getPrivateCredentials().contains(pc)) {
224         subject.getPrivateCredentials().add(pc);
225             }
226         // in any case, clean out state
227
username = null;
228         for (int i = 0; i < password.length; i++){
229         password[i] = ' ';
230             }
231         password = null;
232         commitSucceeded = true;
233         return true;
234     }
235     }
236
237     /**
238      * <p> This method is called if the LoginContext's
239      * overall authentication failed.
240      * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
241      * did not succeed).
242      *
243      * <p> If this LoginModule's own authentication attempt
244      * succeeded (checked by retrieving the private state saved by the
245      * <code>login</code> and <code>commit</code> methods),
246      * then this method cleans up any state that was originally saved.
247      *
248      * <p>
249      *
250      * @exception LoginException if the abort fails.
251      *
252      * @return false if this LoginModule's own login and/or commit attempts
253      * failed, and true otherwise.
254      */

255     public boolean abort() throws LoginException {
256     if (succeeded == false) {
257         return false;
258     } else if (succeeded == true && commitSucceeded == false) {
259         // login succeeded but overall authentication failed
260
succeeded = false;
261         username = null;
262         if (password != null) {
263         for (int i = 0; i < password.length; i++){
264             password[i] = ' ';
265                 }
266         password = null;
267         }
268         userPrincipal = null;
269     } else {
270         // overall authentication succeeded and commit succeeded,
271
// but someone else's commit failed
272
logout();
273     }
274     return true;
275     }
276
277     /**
278      * Logout the user.
279      *
280      * <p> This method removes the <code>PrincipalImpl</code>
281      * that was added by the <code>commit</code> method.
282      *
283      * <p>
284      *
285      * @exception LoginException if the logout fails.
286      *
287      * @return true in all cases since this <code>LoginModule</code>
288      * should not be ignored.
289      */

290     public boolean logout() throws LoginException {
291
292     subject.getPrincipals().remove(userPrincipal);
293     succeeded = false;
294     succeeded = commitSucceeded;
295     username = null;
296     if (password != null) {
297         for (int i = 0; i < password.length; i++){
298         password[i] = ' ';
299             }
300         password = null;
301     }
302     userPrincipal = null;
303     return true;
304     }
305 }
306
Popular Tags