View Javadoc

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          
63          public JAASUserInfo (UserInfo u)
64          {
65              setUserInfo(u);
66          }
67          
68          public String getUserName ()
69          {
70              return this.user.getUserName();
71          }
72          
73          public Principal getPrincipal()
74          {
75              return this.principal;
76          }
77          
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          
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          
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         
106         public boolean checkCredential (Object suppliedCredential)
107         {
108             return this.user.checkCredential(suppliedCredential);
109         }
110     }
111     
112     
113     
114     public Subject getSubject ()
115     {
116         return this.subject;
117     }
118     
119     public void setSubject (Subject s)
120     {
121         this.subject = s;
122     }
123     
124     public JAASUserInfo getCurrentUser()
125     {
126         return this.currentUser;
127     }
128     
129     public void setCurrentUser (JAASUserInfo u)
130     {
131         this.currentUser = u;
132     }
133     
134     public CallbackHandler getCallbackHandler()
135     {
136         return this.callbackHandler;
137     }
138     
139     public void setCallbackHandler(CallbackHandler h)
140     {
141         this.callbackHandler = h; 
142     }
143     
144     public boolean isAuthenticated()
145     {
146         return this.authState;
147     }
148     
149     public boolean isCommitted ()
150     {
151         return this.commitState;
152     }
153     
154     public void setAuthenticated (boolean authState)
155     {
156         this.authState = authState;
157     }
158     
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      */
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      */
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     
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     
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      */
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      */
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      */
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 }