package org.cloudgraph.web.jaas; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cloudgraph.web.sdo.personalization.User; import org.cloudgraph.web.sdo.personalization.UserRole; import org.cloudgraph.web.sdo.personalization.query.QUser; import org.plasma.sdo.access.client.SDODataAccessClient; import commonj.sdo.DataGraph; public class TomcatLoginModule implements LoginModule { private CallbackHandler handler; private Subject subject; private UserPrincipal userPrincipal; private RolePrincipal rolePrincipal; private String login; private List<String> userGroups; private static Log log =LogFactory.getLog( TomcatLoginModule.class); @Override public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { handler = callbackHandler; this.subject = subject; } @Override public boolean login() throws LoginException { Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback("login"); callbacks[1] = new PasswordCallback("password", true); try { handler.handle(callbacks); String name = ((NameCallback) callbacks[0]).getName(); String password = String.valueOf(((PasswordCallback) callbacks[1]) .getPassword()); User user = findUser(name, password); if (user != null) { userGroups = new ArrayList<String>(); for (UserRole userRole : user.getUserRole()) { userGroups.add(userRole.getRole().getName()); } if (userGroups.size() == 0) throw new LoginException("Authentication failed - user '" + name + "' has no roles"); login = name; return true; } else throw new LoginException("Authentication failed - invalid username and/or password"); } catch (IOException e) { throw new LoginException(e.getMessage()); } catch (UnsupportedCallbackException e) { throw new LoginException(e.getMessage()); } } private User findUser(String username, String password) { QUser root = QUser.newQuery(); root.select(root.wildcard()) .select(root.userRole().wildcard()) .select(root.userRole().role().wildcard()); root.where(root.username().eq(username) .and(root.password().eq(password))); SDODataAccessClient service = new SDODataAccessClient(); DataGraph[] results = service.find(root); if (results == null || results.length == 0) return null; User user = (User)results[0].getRootObject(); String dump = user.dump(); return user; } @Override public boolean commit() throws LoginException { userPrincipal = new UserPrincipal(login); subject.getPrincipals().add(userPrincipal); if (userGroups != null && userGroups.size() > 0) { for (String groupName : userGroups) { rolePrincipal = new RolePrincipal(groupName); subject.getPrincipals().add(rolePrincipal); } } return true; } @Override public boolean abort() throws LoginException { return false; } @Override public boolean logout() throws LoginException { subject.getPrincipals().remove(userPrincipal); subject.getPrincipals().remove(rolePrincipal); return true; } }