1 // ========================================================================
2 // $Id: AbstractLoginModule.java 641 2006-07-04 13:15:38Z tvernum $
3 // Copyright 1999-2004 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 
16 package org.mortbay.jetty.plus.jaas.spi;
17 
18 import java.io.IOException;
19 import java.security.Principal;
20 import java.util.ArrayList;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 
25 import javax.security.auth.Subject;
26 import javax.security.auth.callback.Callback;
27 import javax.security.auth.callback.CallbackHandler;
28 import javax.security.auth.callback.NameCallback;
29 import javax.security.auth.callback.UnsupportedCallbackException;
30 import javax.security.auth.login.LoginException;
31 import javax.security.auth.spi.LoginModule;
32 
33 import org.mortbay.jetty.plus.jaas.JAASPrincipal;
34 import org.mortbay.jetty.plus.jaas.JAASRole;
35 import org.mortbay.jetty.plus.jaas.callback.ObjectCallback;
36 
37 /**
38  * AbstractLoginModule
39  *
40  * Abstract base class for all LoginModules. Subclasses should
41  * just need to implement getUserInfo method.
42  *
43  */
44 public abstract class AbstractLoginModule implements LoginModule
45 {
46     private CallbackHandler callbackHandler;
47 
48     private boolean authState = false;
49     private boolean commitState = false;
50     private JAASUserInfo currentUser;
51     private Subject subject;
52 
53 
54 
55     public class JAASUserInfo
56     {
57         private UserInfo user;
58         private Principal principal;
59         private List roles;
60 
61 
62 
JAASUserInfo(UserInfo u)63         public JAASUserInfo (UserInfo u)
64         {
65             setUserInfo(u);
66         }
67 
getUserName()68         public String getUserName ()
69         {
70             return this.user.getUserName();
71         }
72 
getPrincipal()73         public Principal getPrincipal()
74         {
75             return this.principal;
76         }
77 
setUserInfo(UserInfo u)78         public void setUserInfo (UserInfo u)
79         {
80             this.user = u;
81             this.principal = new JAASPrincipal(u.getUserName());
82             this.roles = new ArrayList();
83             if (u.getRoleNames() != null)
84             {
85                 Iterator itor = u.getRoleNames().iterator();
86                 while (itor.hasNext())
87                     this.roles.add(new JAASRole((String)itor.next()));
88             }
89         }
90 
91 
setJAASInfo(Subject subject)92         public void setJAASInfo (Subject subject)
93         {
94             subject.getPrincipals().add(this.principal);
95             subject.getPrivateCredentials().add(this.user.getCredential());
96             subject.getPrincipals().addAll(roles);
97         }
98 
unsetJAASInfo(Subject subject)99         public void unsetJAASInfo (Subject subject)
100         {
101             subject.getPrincipals().remove(this.principal);
102             subject.getPrivateCredentials().remove(this.user.getCredential());
103             subject.getPrincipals().removeAll(this.roles);
104         }
105 
checkCredential(Object suppliedCredential)106         public boolean checkCredential (Object suppliedCredential)
107         {
108             return this.user.checkCredential(suppliedCredential);
109         }
110     }
111 
112 
113 
getSubject()114     public Subject getSubject ()
115     {
116         return this.subject;
117     }
118 
setSubject(Subject s)119     public void setSubject (Subject s)
120     {
121         this.subject = s;
122     }
123 
getCurrentUser()124     public JAASUserInfo getCurrentUser()
125     {
126         return this.currentUser;
127     }
128 
setCurrentUser(JAASUserInfo u)129     public void setCurrentUser (JAASUserInfo u)
130     {
131         this.currentUser = u;
132     }
133 
getCallbackHandler()134     public CallbackHandler getCallbackHandler()
135     {
136         return this.callbackHandler;
137     }
138 
setCallbackHandler(CallbackHandler h)139     public void setCallbackHandler(CallbackHandler h)
140     {
141         this.callbackHandler = h;
142     }
143 
isAuthenticated()144     public boolean isAuthenticated()
145     {
146         return this.authState;
147     }
148 
isCommitted()149     public boolean isCommitted ()
150     {
151         return this.commitState;
152     }
153 
setAuthenticated(boolean authState)154     public void setAuthenticated (boolean authState)
155     {
156         this.authState = authState;
157     }
158 
setCommitted(boolean commitState)159     public void setCommitted (boolean commitState)
160     {
161         this.commitState = commitState;
162     }
163     /**
164      * @see javax.security.auth.spi.LoginModule#abort()
165      * @throws LoginException
166      */
abort()167     public boolean abort() throws LoginException
168     {
169         this.currentUser = null;
170         return (isAuthenticated() && isCommitted());
171     }
172 
173     /**
174      * @see javax.security.auth.spi.LoginModule#commit()
175      * @return
176      * @throws LoginException
177      */
commit()178     public boolean commit() throws LoginException
179     {
180 
181         if (!isAuthenticated())
182         {
183             currentUser = null;
184             setCommitted(false);
185             return false;
186         }
187 
188         setCommitted(true);
189         currentUser.setJAASInfo(subject);
190         return true;
191     }
192 
193 
configureCallbacks()194     public Callback[] configureCallbacks ()
195     {
196 
197         Callback[] callbacks = new Callback[2];
198         callbacks[0] = new NameCallback("Enter user name");
199         callbacks[1] = new ObjectCallback();
200         return callbacks;
201     }
202 
203 
204 
getUserInfo(String username)205     public abstract UserInfo getUserInfo (String username) throws Exception;
206 
207 
208 
209     /**
210      * @see javax.security.auth.spi.LoginModule#login()
211      * @return
212      * @throws LoginException
213      */
login()214     public boolean login() throws LoginException
215     {
216         try
217         {
218             if (callbackHandler == null)
219                 throw new LoginException ("No callback handler");
220 
221             Callback[] callbacks = configureCallbacks();
222             callbackHandler.handle(callbacks);
223 
224             String webUserName = ((NameCallback)callbacks[0]).getName();
225             Object webCredential = ((ObjectCallback)callbacks[1]).getObject();
226 
227             if ((webUserName == null) || (webCredential == null))
228             {
229                 setAuthenticated(false);
230                 return isAuthenticated();
231             }
232 
233             UserInfo userInfo = getUserInfo(webUserName);
234 
235             if (userInfo == null)
236             {
237                 setAuthenticated(false);
238                 return isAuthenticated();
239             }
240 
241             currentUser = new JAASUserInfo(userInfo);
242             setAuthenticated(currentUser.checkCredential(webCredential));
243             return isAuthenticated();
244         }
245         catch (IOException e)
246         {
247             throw new LoginException (e.toString());
248         }
249         catch (UnsupportedCallbackException e)
250         {
251             throw new LoginException (e.toString());
252         }
253         catch (Exception e)
254         {
255             e.printStackTrace();
256             throw new LoginException (e.toString());
257         }
258     }
259 
260     /**
261      * @see javax.security.auth.spi.LoginModule#logout()
262      * @return
263      * @throws LoginException
264      */
logout()265     public boolean logout() throws LoginException
266     {
267         this.currentUser.unsetJAASInfo(this.subject);
268         return true;
269     }
270 
271     /**
272      * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
273      * @param subject
274      * @param callbackHandler
275      * @param sharedState
276      * @param options
277      */
initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)278     public void initialize(Subject subject, CallbackHandler callbackHandler,
279             Map sharedState, Map options)
280     {
281         this.callbackHandler = callbackHandler;
282         this.subject = subject;
283     }
284 
285 }
286