View Javadoc

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