00001
00026 package org.objectweb.jonas.security.auth.spi;
00027
00028 import java.util.ArrayList;
00029 import java.util.Map;
00030
00031 import javax.naming.InitialContext;
00032 import javax.security.auth.Subject;
00033 import javax.security.auth.callback.Callback;
00034 import javax.security.auth.callback.CallbackHandler;
00035 import javax.security.auth.callback.NameCallback;
00036 import javax.security.auth.callback.PasswordCallback;
00037 import javax.security.auth.login.LoginException;
00038 import javax.security.auth.spi.LoginModule;
00039
00040 import org.objectweb.jonas.security.auth.JGroup;
00041 import org.objectweb.jonas.security.auth.JPrincipal;
00042 import org.objectweb.jonas.security.auth.JRole;
00043 import org.objectweb.jonas.security.auth.callback.CertificateCallback;
00044 import org.objectweb.jonas.security.realm.factory.JResource;
00045 import org.objectweb.jonas.security.realm.factory.JResourceException;
00046 import org.objectweb.jonas.security.realm.principals.User;
00047
00055 public class JResourceLoginModule implements LoginModule {
00056
00060 private Subject subject = null;
00061
00065 private CallbackHandler callbackHandler = null;
00066
00070 private Map options = null;
00071
00075 private String principalName = null;
00076
00080 private String password = null;
00081
00085 private ArrayList principalRoles = null;
00086
00090 private boolean loginWasDoneWithSuccess = false;;
00091
00105 public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
00106 this.subject = subject;
00107 this.callbackHandler = callbackHandler;
00108 this.options = options;
00109 }
00110
00121 public boolean login() throws LoginException {
00122
00123
00124 if (callbackHandler == null) {
00125 throw new LoginException("No handler has been defined.");
00126 }
00127
00128
00129 String resourceName = (String) options.get("resourceName");
00130
00131
00132 String certCallback = (String) options.get("certCallback");
00133
00134
00135 if (resourceName == null) {
00136 throw new LoginException(
00137 "You have to give an argument to this login module. The 'resourceName' parameter is required.");
00138 }
00139
00140
00141 try {
00142 InitialContext ictx = new InitialContext();
00143 JResource jResource = null;
00144 try {
00145 jResource = (JResource) ictx.lookup(resourceName);
00146 } catch (Exception e) {
00147 throw createChainedLoginException("Cannot retrieve the resource '" + resourceName
00148 + "'. Check that this resource is bound in the registry", e);
00149 }
00150
00151
00152 NameCallback nameCallback = new NameCallback("User :");
00153
00154 PasswordCallback passwordCallback = new PasswordCallback("Password :", false);
00155 CertificateCallback certificateCallback = new CertificateCallback();
00156 Callback[] callbacks = null;
00157
00158 if ((certCallback != null) && (Boolean.valueOf(certCallback).booleanValue())) {
00159 callbacks = new Callback[] {nameCallback, passwordCallback, certificateCallback};
00160 } else {
00161 callbacks = new Callback[] {nameCallback, passwordCallback};
00162 }
00163 callbackHandler.handle(callbacks);
00164
00165
00166 principalName = nameCallback.getName();
00167 if (principalName == null) {
00168 throw new LoginException("A null username is not a valid username");
00169 }
00170 if (principalName.startsWith("##DN##") && (certificateCallback.getUserCertificate() == null)) {
00171 throw new LoginException("Name must have a certificate to access this certificate based access login");
00172 }
00173 char[] arrayPass = passwordCallback.getPassword();
00174 if (arrayPass == null) {
00175 throw new LoginException("A null password is not a valid password");
00176 }
00177
00178
00179 User user = null;
00180 try {
00181 user = jResource.findUser(principalName);
00182 } catch (Exception jre) {
00183
00184 throw createChainedLoginException("Can not find the user", jre);
00185 }
00186
00187 if (user == null) {
00188 throw new LoginException("User '" + principalName + "' not found.");
00189 }
00190
00191
00192 boolean validated = jResource.isValidUser(user, new String(arrayPass));
00193 if (!validated) {
00194 throw new LoginException("The password for the user '" + principalName + "' is not valid");
00195 }
00196 this.password = user.getPassword();
00197
00198 try {
00199 principalRoles = jResource.getArrayListCombinedRoles(user);
00200 } catch (JResourceException jre) {
00201 throw createChainedLoginException(jre.getMessage(), jre);
00202 }
00203
00204 } catch (Exception e) {
00205 throw createChainedLoginException("Error during the login phase : " + e.getMessage(), e);
00206 }
00207 loginWasDoneWithSuccess = true;
00208 return true;
00209 }
00210
00217 private static LoginException createChainedLoginException(String msg, Exception e) {
00218 LoginException le = new LoginException(msg);
00219 le.initCause(e);
00220 return le;
00221 }
00222
00237 public boolean commit() throws LoginException {
00238
00239
00240 if (loginWasDoneWithSuccess) {
00241
00242 subject.getPrincipals().add(new JPrincipal(principalName));
00243 subject.getPrivateCredentials().add(password);
00244 JGroup group = new JGroup("Roles");
00245
00246
00247 String[] roles = new String[principalRoles.size()];
00248 roles = (String[]) principalRoles.toArray(roles);
00249 int size = principalRoles.size();
00250 for (int i = 0; i < size; i++) {
00251 group.addMember(new JRole(roles[i]));
00252 }
00253
00254
00255 subject.getPrincipals().add(group);
00256 }
00257 return loginWasDoneWithSuccess;
00258 }
00259
00271 public boolean abort() throws LoginException {
00272
00273 if (loginWasDoneWithSuccess) {
00274
00275 principalName = null;
00276 principalRoles = null;
00277 }
00278 return loginWasDoneWithSuccess;
00279 }
00280
00288 public boolean logout() throws LoginException {
00289
00290
00291 if (loginWasDoneWithSuccess) {
00292
00293 subject.getPrincipals().remove(new JPrincipal(principalName));
00294 }
00295
00296 return loginWasDoneWithSuccess;
00297 }
00298
00299 }