Created
March 20, 2014 15:44
-
-
Save jeanouii/9666739 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * <p>This LoginModule aims at using the default tomcat-users.xml file for authenticating and provisioning roles to a | |
| * user.</p> | |
| * <p/> | |
| * <p>This login module is indented to be wrapped by the CDILoginModule provided by TomEE. So that it's possible to | |
| * get the Tomcat UserDatabase using a common injection.</p> | |
| * <p/> | |
| * <p>Configuration in Tomcat/TomEE</p> | |
| * <ul> | |
| * <li>Add the UserDatabase resource (or check it's already defined.</li> | |
| * <pre> | |
| * <!-- Global JNDI resources | |
| * Documentation at /docs/jndi-resources-howto.html | |
| * --> | |
| * <GlobalNamingResources> | |
| * <!-- Editable user database that can also be used by | |
| * UserDatabaseRealm to authenticate users | |
| * --> | |
| * <Resource name="UserDatabase" auth="Container" | |
| * type="org.apache.catalina.UserDatabase" | |
| * description="User database that can be updated and saved" | |
| * factory="org.apache.catalina.users.MemoryUserDatabaseFactory" | |
| * pathname="conf/tomcat-users.xml" /> | |
| * </GlobalNamingResources> | |
| * </pre> | |
| * | |
| * <li>Configure the JAASRealm in Tomcat/TomEE</li> | |
| * <pre> | |
| * <Realm className="org.apache.catalina.realm.JAASRealm" | |
| * appName="applicationNameInJaasConfig" | |
| * userClassNames="org.apache.openejb.core.security.jaas.UserPrincipal" | |
| * roleClassNames="org.apache.openejb.core.security.jaas.GroupPrincipal"/> | |
| * </pre> | |
| * | |
| * <li>Configure JAAS LoginModule in <code>jaas.config</code>. <strong>This module must be wrapped into the | |
| * TomEE provided CDILoginModule to have CDI features.</strong></li> | |
| * <pre> | |
| * applicationNameInJaasConfig { | |
| * org.apache.openejb.core.security.jaas.CDILoginModule required | |
| * delegate="com.tomitribe.security.jaas.TomcatUsersLoginModule" | |
| * loginModuleAsCdiBean=true; | |
| }; | |
| * </pre> | |
| * </ul> | |
| */ | |
| public class TomcatUsersLoginModule implements LoginModule { | |
| private static Logger LOGGER = Logger.getLogger(TomcatUsersLoginModule.class.getName()); | |
| @Resource | |
| private UserDatabase userDatabase; | |
| private Subject subject; | |
| private CallbackHandler callbackHandler; | |
| private Map<String, Object> sharedState; | |
| private Map<String, ?> options; | |
| private boolean debug; | |
| private String username; | |
| private User user; | |
| private Set principals = new LinkedHashSet(); | |
| @Override | |
| public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, | |
| Map<String, ?> options) { | |
| this.subject = subject; | |
| this.callbackHandler = callbackHandler; | |
| this.sharedState = (Map<String, Object>) sharedState; | |
| this.options = options; | |
| debug = "true".equalsIgnoreCase((String) options.get("debug")); | |
| } | |
| @Override | |
| public boolean login() throws LoginException { | |
| Callback[] callbacks = new Callback[2]; | |
| callbacks[0] = new NameCallback("Username: "); | |
| callbacks[1] = new PasswordCallback("Password: ", false); | |
| try { | |
| callbackHandler.handle(callbacks); | |
| } catch (IOException ioe) { | |
| throw new LoginException(ioe.getMessage()); | |
| } catch (UnsupportedCallbackException uce) { | |
| throw new LoginException(uce.getMessage() + " not available to obtain information from user"); | |
| } | |
| username = ((NameCallback) callbacks[0]).getName(); | |
| char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword(); | |
| if (tmpPassword == null) tmpPassword = new char[0]; | |
| user = userDatabase.findUser(username); | |
| if (user == null) throw new FailedLoginException("User does not exist"); | |
| String password = user.getPassword(); | |
| if (!password.equals(new String(tmpPassword))) throw new FailedLoginException("Password does not match"); | |
| if (debug) { | |
| LOGGER.fine("Logged in as '" + user + "'"); | |
| } | |
| return true; | |
| } | |
| @Override | |
| public boolean commit() throws LoginException { | |
| principals.add(new UserPrincipal(username)); | |
| Iterator<Role> uRoles = user.getRoles(); | |
| while (uRoles.hasNext()) { | |
| Role role = uRoles.next(); | |
| principals.add(new GroupPrincipal(role.getName())); | |
| } | |
| Iterator<Group> uGroups = user.getGroups(); | |
| while (uGroups.hasNext()) { | |
| Group group = uGroups.next(); | |
| uRoles = group.getRoles(); | |
| while (uRoles.hasNext()) { | |
| Role role = uRoles.next(); | |
| principals.add(new GroupPrincipal(role.getName())); | |
| } | |
| } | |
| subject.getPrincipals().addAll(principals); | |
| if (debug) { | |
| LOGGER.fine("Commit for user '" + user + "'"); | |
| } | |
| return true; | |
| } | |
| @Override | |
| public boolean abort() throws LoginException { | |
| clear(); | |
| if (debug) { | |
| LOGGER.fine("Abort"); | |
| } | |
| return true; | |
| } | |
| private void clear() { | |
| principals.clear(); | |
| user = null; | |
| username = null; | |
| } | |
| @Override | |
| public boolean logout() throws LoginException { | |
| clear(); | |
| if (debug) { | |
| LOGGER.fine("Logged out for user'" + user + "'"); | |
| } | |
| return true; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment