Source code: com/clra/member/Authentication.java
1 /*
2 * Copyright (c) Carnegie Lake Rowing Association 2002. All rights reserved.
3 * Distributed under the GPL license. See doc/COPYING.
4 * $RCSfile: Authentication.java,v $
5 * $Date: 2003/02/26 03:38:45 $
6 * $Revision: 1.4 $
7 */
8
9 package com.clra.member;
10
11 import java.security.Principal;
12 import javax.security.auth.Subject;
13 import java.io.IOException;
14 import java.io.Serializable;
15 import java.util.Iterator;
16 import javax.security.auth.login.LoginContext;
17 import javax.security.auth.login.LoginException;
18 import javax.security.auth.callback.Callback;
19 import javax.security.auth.callback.CallbackHandler;
20 import javax.security.auth.callback.NameCallback;
21 import javax.security.auth.callback.PasswordCallback;
22 import javax.security.auth.callback.PasswordCallback;
23 import javax.security.auth.callback.UnsupportedCallbackException;
24 import org.apache.log4j.Category;
25 import org.jboss.security.SecurityAssociation;
26
27 /**
28 * Authenticates a user during login, and releases the authentication
29 * during logout.<p>
30 *
31 * Note: This class is NOT secure, because it stores passwords in plain
32 * text. This isn't an issue unless the rowing association starts
33 * doing e-commerce. The plain-text issue is important when web objects
34 * use Authentication instances, because they typically stick them into
35 * HttpSessions, where they can be deserialized to any old location.<p>
36 *
37 * @version $Id: Authentication.java,v 1.4 2003/02/26 03:38:45 rphall Exp $
38 * @author <a href="mailto:rphall@pluto.njcc.com">Rick Hall</a>
39 */
40 public class Authentication implements CallbackHandler, Serializable {
41
42 private final static String base = Authentication.class.getName();
43 private final static Category theLog = Category.getInstance( base );
44
45 private final String user;
46 private final String password;
47 private LoginContext ctx = null; // Should be transient?
48
49 public Authentication( String user, String password ) {
50
51 theLog.debug( "user == '" + user + "'" );
52 theLog.debug( "password == '" + password + "'" );
53
54 // Assign blank finals
55 this.user = user;
56 this.password = password;
57
58 // Enforce preconditions
59 if ( user == null || user.trim().length() == 0 ) {
60 throw new IllegalArgumentException( "invalid user" );
61 }
62 if ( password == null || password.trim().length() == 0 ) {
63 throw new IllegalArgumentException( "invalid password" );
64 }
65
66 } // ctor(String,String)
67
68 public void login() throws LoginException {
69
70 if ( theLog.isDebugEnabled() ) {
71 theLog.debug( "login '" + this.user + "'" );
72 Principal p = SecurityAssociation.getPrincipal();
73 String msg = ( p==null ? null : p.getName() );
74 theLog.debug( this.user + ": preSAPrincip == '" + msg + "'" );
75 Object c = SecurityAssociation.getCredential();
76 msg = ( c==null ? null : c.toString() );
77 theLog.debug( this.user + ": preSACredent == '" + msg + "'" );
78 }
79 if ( this.ctx == null ) {
80 this.ctx = new LoginContext( Configuration.LOGIN_CONTEXT, this );
81 }
82 this.ctx.login();
83
84 if ( theLog.isDebugEnabled() ) {
85 theLog.debug( "login '" + this.user + "'" );
86 Principal p = SecurityAssociation.getPrincipal();
87 String msg = ( p==null ? null : p.getName() );
88 theLog.debug( this.user + ": postSAPrincip == '" + msg + "'" );
89 Object c = SecurityAssociation.getCredential();
90 msg = ( c==null ? null : c.toString() );
91 theLog.debug( this.user + ": postSACredent == '" + msg + "'" );
92 }
93 if ( theLog.isDebugEnabled() ) {
94 Subject s = this.ctx.getSubject();
95 theLog.debug( this.user + ": Subject readonly == " + s.isReadOnly() );
96 theLog.debug( this.user + ": Subject == '" + s.toString() + "'" );
97 Iterator iter = s.getPrincipals().iterator();
98 while( iter.hasNext() ) {
99 Principal p = (Principal) iter.next();
100 theLog.debug( this.user + ": Principal == '" + p.getName() + "'" );
101 }
102 iter = s.getPublicCredentials().iterator();
103 while( iter.hasNext() ) {
104 Object c = iter.next();
105 String info = c.getClass().getName() + "(" + c.toString() + ")";
106 theLog.debug( this.user + ": PublicCredential == " + info );
107 }
108 iter = s.getPrivateCredentials().iterator();
109 while( iter.hasNext() ) {
110 Object c = iter.next();
111 String info = c.getClass().getName() + "(" + c.toString() + ")";
112 theLog.debug( this.user + ": PrivateCredential == " + info );
113 }
114 }
115
116 } // login()
117
118 public void logout() throws LoginException {
119 theLog.debug( "logout '" + this.user + "'" );
120 if ( this.ctx != null ) {
121 this.ctx.logout();
122 }
123 this.ctx = null;
124 } // logout()
125
126 protected void finalize() {
127 try {
128 logout();
129 }
130 catch( Exception x ) {
131 this.ctx = null;
132 }
133 } // finalize()
134
135 public void handle( Callback[] callbacks )
136 throws IOException, UnsupportedCallbackException {
137
138 for (int i = 0; i < callbacks.length; i++) {
139
140 if (callbacks[i] instanceof NameCallback) {
141 theLog.debug( "name Callback for '" + this.user + "'" );
142 NameCallback nc = (NameCallback)callbacks[i];
143 nc.setName( this.user );
144 }
145 else if (callbacks[i] instanceof PasswordCallback) {
146 theLog.debug( "password Callback for '" + this.user + "'" );
147 PasswordCallback pc = (PasswordCallback)callbacks[i];
148 pc.setPassword( this.password.toCharArray() );
149 }
150 else {
151 theLog.debug( "unexpected Callback for '" + this.user + "'" );
152 String msg = "Unrecognized callback == " + callbacks[i].toString();
153 throw new UnsupportedCallbackException( callbacks[i], msg );
154 }
155
156 } // for
157
158 return;
159 } // handle(Callback[])
160
161 } // Authentication
162
163 /*
164 * $Log: Authentication.java,v $
165 * Revision 1.4 2003/02/26 03:38:45 rphall
166 * Added copyright and GPL license
167 *
168 * Revision 1.3 2003/02/19 22:23:02 rphall
169 * Removed gratuitous use of CLRA acronym
170 *
171 * Revision 1.2 2002/02/18 18:03:10 rphall
172 * Ran dos2unix to remove ^M (carriage return) from end of lines
173 *
174 * Revision 1.1.1.1 2002/01/03 21:57:28 rphall
175 * Initial load, 5th try, Jan-03-2002 4:57 PM
176 *
177 * Revision 1.1 2001/11/28 12:14:06 rphall
178 * Authenticates a user during login
179 *
180 */
181