2 * This document is a part of the source code and related artifacts
\r
3 * for CollectionSpace, an open source collections management system
\r
4 * for museums and related institutions:
\r
6 * http://www.collectionspace.org
\r
7 * http://wiki.collectionspace.org
\r
9 * Copyright 2009 University of California at Berkeley
\r
11 * Licensed under the Educational Community License (ECL), Version 2.0.
\r
12 * You may not use this file except in compliance with this License.
\r
14 * You may obtain a copy of the ECL 2.0 License at
\r
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
\r
18 * Unless required by applicable law or agreed to in writing, software
\r
19 * distributed under the License is distributed on an "AS IS" BASIS,
\r
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
21 * See the License for the specific language governing permissions and
\r
22 * limitations under the License.
\r
24 package org.collectionspace.authentication.jaas;
\r
26 import java.util.ArrayList;
\r
27 import java.util.Collection;
\r
28 import java.util.List;
\r
29 import java.util.Map;
\r
30 import java.security.acl.Group;
\r
32 import javax.security.auth.Subject;
\r
33 import javax.security.auth.callback.CallbackHandler;
\r
34 import javax.security.auth.login.LoginException;
\r
36 import org.collectionspace.authentication.realm.db.CSpaceDbRealm;
\r
37 import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
\r
38 import org.slf4j.Logger;
\r
39 import org.slf4j.LoggerFactory;
\r
42 * CollectionSpace default identity provider supporting multi-tenancy
\r
45 public class CSpaceJBossDBLoginModule extends UsernamePasswordLoginModule {
\r
47 private Logger logger = LoggerFactory.getLogger(CSpaceJBossDBLoginModule.class);
\r
49 private CSpaceDbRealm realm;
\r
52 * Initialize CSpaceDBLoginModule
\r
55 * dsJndiName: The name of the DataSource of the database containing the
\r
56 * Principals, Roles tables
\r
57 * principalsQuery: The prepared statement query, equivalent to:
\r
58 * "select Password from Principals where PrincipalID=?"
\r
59 * rolesQuery: The prepared statement query, equivalent to:
\r
60 * "select Role, RoleGroup from Roles where PrincipalID=?"
\r
62 * "select TenantId, TenantName, TenantGroup from Tenants where PrincipalID=?"
\r
64 public void initialize(Subject subject, CallbackHandler callbackHandler,
\r
65 Map sharedState, Map options) {
\r
66 super.initialize(subject, callbackHandler, sharedState, options);
\r
67 realm = new CSpaceDbRealm(options);
\r
71 protected String createPasswordHash(String username, String password,
\r
72 String digestOption)
\r
73 throws LoginException {
\r
74 String result = super.createPasswordHash(username, password, digestOption);
\r
76 if (result == null) {
\r
77 String message = "Could not create a password hash for the supplied password. Check your login.conf configuration's hash algorithm setting.";
\r
79 throw new LoginException(message);
\r
85 protected String getUsersPassword() throws LoginException {
\r
87 String username = getUsername();
\r
88 String password = null;
\r
91 password = realm.getUsersPassword(username);
\r
92 password = convertRawPassword(password);
\r
93 if (logger.isDebugEnabled()) {
\r
94 logger.debug("Obtained user password for: " + username);
\r
96 } catch (LoginException lex) {
\r
97 log.error("Could not retrieve user password for: " + username, lex);
\r
99 } catch (Exception ex) {
\r
100 log.error("Could not retrieve user password for: " + username, ex);
\r
101 LoginException le = new LoginException("Unknown Exception");
\r
110 public boolean commit() throws LoginException {
\r
112 result = super.commit();
\r
117 public boolean abort() throws LoginException {
\r
119 result = super.abort();
\r
123 /** Execute the rolesQuery against the dsJndiName to obtain the roles for
\r
124 the authenticated user.
\r
126 @return Group[] containing the sets of roles
\r
128 protected Group[] getRoleSets() throws LoginException {
\r
129 String username = getUsername();
\r
131 Collection<Group> roles = realm.getRoles(username,
\r
132 "org.collectionspace.authentication.CSpacePrincipal",
\r
133 "org.jboss.security.SimpleGroup");
\r
135 Collection<Group> tenants = realm.getTenants(username,
\r
136 "org.jboss.security.SimpleGroup");
\r
138 List<Group> all = new ArrayList<Group>();
\r
140 all.addAll(tenants);
\r
141 Group[] roleSets = new Group[all.size()];
\r
142 all.toArray(roleSets);
\r
146 /** A hook to allow subclasses to convert a password from the database
\r
147 into a plain text string or whatever form is used for matching against
\r
148 the user input. It is called from within the getUsersPassword() method.
\r
149 @param rawPassword - the password as obtained from the database
\r
150 @return the argument rawPassword
\r
152 protected String convertRawPassword(String rawPassword) {
\r
153 return rawPassword;
\r