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