<Context antiResourceLocking="false" privileged="true" path="/cspace-services"
docBase="cspace-services">
- <!--
- Setup the security realm for the CollectionSpace services
- -->
- <Realm className="org.apache.catalina.realm.JAASRealm" appName="CSpaceJBossDBLoginModule"
- userClassNames="org.collectionspace.authentication.CSpacePrincipal"
- roleClassNames="org.collectionspace.authentication.CSpacePrincipal"/>
-
<!-- Disable HTTP Session persistence between restart since webengine session objects are not serializable -->
<Manager pathname=""/>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
+ xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
- http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
+ http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<!--
debugging tips : enable following categories in
</sec:http>
<sec:authentication-manager id="userAuthenticationManager">
- <sec:authentication-provider ref="jaasAuthenticationProvider"/>
+ <sec:authentication-provider ref="daoAuthenticationProvider"/>
</sec:authentication-manager>
- <bean id="jaasAuthenticationProvider"
- class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
- <property name="loginContextName">
- <value>cspace</value> <!-- value should be same as in application-policy in JBoss login-config.xml -->
- </property>
- <property name="loginConfig">
- <value>/WEB-INF/login.conf</value>
- </property>
- <property name="callbackHandlers">
- <list>
- <bean class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
- <bean class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler"/>
- </list>
- </property>
- <property name="authorityGranters">
- <list>
- <bean class="org.collectionspace.authentication.spring.CSpaceAuthorityGranter"/>
- </list>
+ <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
+ <property name="userDetailsService" ref="userDetailsService" />
+ <property name="passwordEncoder">
+ <bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
+ <constructor-arg value="256"/>
+ <property name="encodeHashAsBase64" value="true" />
+ </bean>
</property>
</bean>
+ <bean id="userDetailsService" class="org.collectionspace.authentication.spring.CSpaceUserDetailsService">
+ <constructor-arg>
+ <bean class="org.collectionspace.authentication.realm.db.CSpaceDbRealm">
+ <constructor-arg>
+ <util:map>
+ <entry key="dsJndiName" value="CspaceDS" />
+ <entry key="principalsQuery" value="select passwd from users where username=?" />
+ <entry key="rolesQuery" value="select r.rolename from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid" />
+ <entry key="tenantsQueryWithDisabled" value="select t.id, t.name from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTS_COMMON_CSID and at.tenant_id = t.id" />
+ <entry key="tenantsQueryNoDisabled" value="select t.id, t.name from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTS_COMMON_CSID and at.tenant_id = t.id and NOT t.disabled" />
+ <entry key="maxRetrySeconds" value="5000" />
+ <entry key="delayBetweenAttemptsMillis" value="200" />
+ </util:map>
+ </constructor-arg>
+ </bean>
+ </constructor-arg>
+ </bean>
+
<sec:authentication-manager id="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserDetailsService"/>
</sec:authentication-manager>
<!-- The scope attribute below is a meaningless placeholder. In the future we may want to use it to limit
the permissions of particular clients. Currently a client has the full permissions of the user on
- behalf of whom it is acting . -->
+ whose behalf it is acting. -->
<oauth:client-details-service id="clientDetails">
<oauth:client
client-id="cspace-ui"
+++ /dev/null
-CSpaceJBossDBLoginModule {
- org.collectionspace.authentication.jaas.CSpaceJBossDBLoginModule required
- dsJndiName="CspaceDS"
- hashAlgorithm="SHA-256"
- ignorePasswordCase="false"
- principalClass="org.collectionspace.authentication.CSpacePrincipal"
- principalsQuery="select passwd from users where username=?"
- rolesQuery="select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid"
- tenantsQueryWithDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTS_COMMON_CSID and at.tenant_id = t.id"
- tenantsQueryNoDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTS_COMMON_CSID and at.tenant_id = t.id and NOT t.disabled"
- maxRetrySeconds="5000"
- delayBetweenAttemptsMillis="200"
- debug=true;
- };
-
- /**
- * The JAAS login configuration.
- */
- cspace {
- org.collectionspace.authentication.jaas.CSpaceJBossDBLoginModule required
- dsJndiName="CspaceDS"
- hashAlgorithm="SHA-256"
- ignorePasswordCase="false"
- principalClass="org.collectionspace.authentication.CSpacePrincipal"
- principalsQuery="select passwd from users where username=?"
- rolesQuery="select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid"
- tenantsQueryWithDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTS_COMMON_CSID and at.tenant_id = t.id"
- tenantsQueryNoDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTS_COMMON_CSID and at.tenant_id = t.id and NOT t.disabled"
- maxRetrySeconds="5000"
- delayBetweenAttemptsMillis="200"
- debug=true;
- };
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
- <url-pattern>/</url-pattern>
+ <url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.2.1</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
*/
package org.collectionspace.authentication;
+import java.util.List;
+
import javax.sql.DataSource;
import org.collectionspace.authentication.spi.AuthNContext;
* getTenantIds returns a list of tenant ids the user is associated with
* @return
*/
- public String[] getTenantIds() {
+ public List<String> getTenantIds() {
return authnContext.getTenantIds();
}
* @see CSpaceTenant
* @return
*/
- public CSpaceTenant[] getTenants() {
+ public List<CSpaceTenant> getTenants() {
return authnContext.getTenants();
}
}
+++ /dev/null
-/**
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
-
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
-
- * Copyright 2009 University of California at Berkeley
-
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
-
- * You may obtain a copy of the ECL 2.0 License at
-
- * https://source.collectionspace.org/collection-space/LICENSE.txt
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.collectionspace.authentication;
-
-import java.security.Principal;
-
-/**
- * CSpacePrincipal provides additional tenant-specific context to application
- * @author
- */
-final public class CSpacePrincipal
- implements Principal, java.io.Serializable {
-
- /**
- *
- */
- private static final long serialVersionUID = -1357683611240908638L;
- private String name;
- private String tenantId;
-
- public CSpacePrincipal(String name) {
- this.name = name;
- }
-
- public int hashCode() {
- return name.hashCode();
- }
-
- public boolean equals(Object obj) {
- Principal p = (Principal) obj;
- return name.equals(p.getName());
- }
-
- public String toString() {
- return name;
- }
-
- /**
- * Returns the name of this principal.
- *
- * @return the name of this principal.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the id of the tenant this principal is associated with
- * @return
- */
- public String getTenantId() {
- return tenantId;
- }
-
- /**
- * Set the id for the tenant to which princiapal is associated with
- * The access to this method must be package private
- * @param tenantId
- */
- void setTenantId(String tenantId) {
- this.tenantId = tenantId;
- }
-}
*/
package org.collectionspace.authentication;
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
/**
- * A CSpace Principal representing a tenant
- * A class derived (in principle) from JBoss SimpleGroup and SimplePrincipal
- * @author
+ * A CollectionSpace tenant.
*/
-public class CSpaceTenant implements Group, Cloneable {
+public class CSpaceTenant {
+ private final String id;
+ private final String name;
- /** The serialVersionUID */
- private static final long serialVersionUID = 1L;
- private String name;
- private String id;
- private HashMap<Principal, Principal> members = new HashMap<Principal, Principal>();
-
- public CSpaceTenant(String name, String id) {
- if(name == null || id == null) {
- String msg = "CSpaceTenant: invalid argument(s), can't be null" +
- "name=" + name + " id=" + id;
- throw new IllegalArgumentException(msg);
- }
- this.name = name;
- this.id = id;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- public String getId() {
- return id;
- }
-
- /**
- * Adds the specified member to the tenant.
- * @param user the principal to add to this tenant.
- * @return true if the member was successfully added,
- * false if the principal was already a member.
- */
- @Override
- public boolean addMember(Principal user) {
- boolean isMember = members.containsKey(user);
- if (isMember == false) {
- members.put(user, user);
- }
- return isMember == false;
- }
-
- /**
- * isMember returns true if the passed principal is a member of the tenant.
- * This method does a recursive search, so if a principal belongs to a
- * tenant which is a member of this tenant, true is returned.
- * @param member the principal whose membership is to be checked.
- * @return true if the principal is a member of this tenant, false otherwise.
+ /**
+ * Creates a CSpaceTenant with a given id and name.
+ *
+ * @param id the tenant id, e.g. "1"
+ * @param name the tenant name, e.g. "core.collectionspace.org"
*/
- @Override
- public boolean isMember(Principal member) {
- // First see if there is a key with the member name
- boolean isMember = members.containsKey(member);
- if (isMember == false) { // Check any tenants for membership
- Collection values = members.values();
- Iterator iter = values.iterator();
- while (isMember == false && iter.hasNext()) {
- Object next = iter.next();
- if (next instanceof Group) {
- Group tenant = (Group) next;
- isMember = tenant.isMember(member);
- }
- }
- }
- return isMember;
+ public CSpaceTenant(String id, String name) {
+ this.id = id;
+ this.name = name;
}
- /**
- * members returns an enumeration of the members in the tenant.
- * The returned objects can be instances of either Principal
- * or Group (which is a subinterface of Principal).
- * @return an enumeration of the tenant members.
- */
@Override
- public Enumeration members() {
- return Collections.enumeration(members.values());
+ public int hashCode() {
+ // The tenant id uniquely identifies the tenant,
+ // regardless of other properties. CSpaceTenants
+ // with the same id should hash identically.
+
+ return new HashCodeBuilder(83, 61)
+ .append(id)
+ .build();
}
- /**
- * removeMember removes the specified member from the tenant.
- * @param user the principal to remove from this tenant.
- * @return true if the principal was removed, or
- * false if the principal was not a member.
- */
@Override
- public boolean removeMember(Principal user) {
- Object prev = members.remove(user);
- return prev != null;
- }
+ public boolean equals(Object obj) {
+ // The tenant id uniquely identifies the tenant,
+ // regardless of other properties. CSpaceTenants
+ // with the same id should be equal.
- /**
- * Compare this tenant against another tenant
- * @return true if name equals another.getName();
- */
- @Override
- public boolean equals(Object another) {
- if (!(another instanceof CSpaceTenant)) {
+ if (obj == null) {
return false;
}
- String anotherName = ((CSpaceTenant) another).getName();
- String anotherId = ((CSpaceTenant) another).getId();
- return name.equals(anotherName) && id.equals(anotherId);
- }
-
- @Override
- public int hashCode() {
- return (name + id).hashCode();
+
+ if (obj == this) {
+ return true;
+ }
+
+ if (obj.getClass() != getClass()) {
+ return false;
+ }
+
+ CSpaceTenant rhs = (CSpaceTenant) obj;
+
+ return new EqualsBuilder()
+ .append(id, rhs.getId())
+ .isEquals();
}
@Override
public String toString() {
- StringBuffer tmp = new StringBuffer(getName());
- tmp.append("(members:");
- Iterator iter = members.keySet().iterator();
- while (iter.hasNext()) {
- tmp.append(iter.next());
- tmp.append(',');
- }
- tmp.setCharAt(tmp.length() - 1, ')');
- return tmp.toString();
+ return new ToStringBuilder(this).
+ append("id", id).
+ append("name", name).
+ toString();
+ }
+
+ public String getId() {
+ return id;
}
- @Override
- public synchronized Object clone() throws CloneNotSupportedException {
- CSpaceTenant clone = (CSpaceTenant) super.clone();
- if (clone != null) {
- clone.members = (HashMap) this.members.clone();
- }
- return clone;
+ public String getName() {
+ return name;
}
}
--- /dev/null
+package org.collectionspace.authentication;
+
+import java.util.Set;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+
+/**
+ * A CollectionSpace user. This class implements the Spring UserDetails interface,
+ * but the enabled, accountNonExpired, credentialsNonExpired, and accountNonLocked
+ * properties are not meaningful and will always be true. CollectionSpace users
+ * may be disabled (aka inactive), but this check is done outside of Spring Security,
+ * after Spring authentication has succeeded.
+ *
+ * @See org.collectionspace.services.common.security.SecurityInterceptor.
+ */
+public class CSpaceUser extends User {
+
+ private static final long serialVersionUID = 3326192720134327612L;
+
+ private Set<CSpaceTenant> tenants;
+
+ /**
+ * Creates a CSpaceUser with the given username, hashed password, associated
+ * tenants, and granted authorities.
+ *
+ * @param username the username, e.g. "admin@core.collectionspace.org"
+ * @param password the hashed password, e.g. "59PnafP1k9rcuGNMxbCfyQ3TphxKBqecsJI2Yv5vrms="
+ * @param tenants the tenants associated with the user
+ * @param authorities the authorities that have been granted to the user
+ */
+ public CSpaceUser(String username, String password,
+ Set<CSpaceTenant> tenants,
+ Set<? extends GrantedAuthority> authorities) {
+
+ super(username, password,
+ true, // enabled
+ true, // accountNonExpired
+ true, // credentialsNonExpired
+ true, // accountNonLocked
+ authorities);
+
+ this.tenants = tenants;
+ }
+
+ /**
+ * Retrieves the tenants associated with the user.
+ *
+ * @return the tenants
+ */
+ public Set<CSpaceTenant> getTenants() {
+ return tenants;
+ }
+}
+++ /dev/null
-/**
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
-
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
-
- * Copyright 2009 University of California at Berkeley
-
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
-
- * You may obtain a copy of the ECL 2.0 License at
-
- * https://source.collectionspace.org/collection-space/LICENSE.txt
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.collectionspace.authentication.jaas;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.security.acl.Group;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
-
-import org.collectionspace.authentication.realm.db.CSpaceDbRealm;
-import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * CollectionSpace default identity provider supporting multi-tenancy
- * @author
- */
-public class CSpaceJBossDBLoginModule extends UsernamePasswordLoginModule {
-
- private Logger logger = LoggerFactory.getLogger(CSpaceJBossDBLoginModule.class);
-
- private CSpaceDbRealm realm;
-
- /**
- * Initialize CSpaceDBLoginModule
- *
- * @param options -
- * dsJndiName: The name of the DataSource of the database containing the
- * Principals, Roles tables
- * principalsQuery: The prepared statement query, equivalent to:
- * "select Password from Principals where PrincipalID=?"
- * rolesQuery: The prepared statement query, equivalent to:
- * "select Role, RoleGroup from Roles where PrincipalID=?"
- * tenantsQuery:
- * "select TenantId, TenantName, TenantGroup from Tenants where PrincipalID=?"
- */
- public void initialize(Subject subject, CallbackHandler callbackHandler,
- Map sharedState, Map options) {
- super.initialize(subject, callbackHandler, sharedState, options);
- realm = new CSpaceDbRealm(options);
- }
-
- @Override
- protected String createPasswordHash(String username, String password,
- String digestOption)
- throws LoginException {
- String result = super.createPasswordHash(username, password, digestOption);
-
- if (result == null) {
- String message = "Could not create a password hash for the supplied password. Check your login.conf configuration's hash algorithm setting.";
- log.error(message);
- throw new LoginException(message);
- }
-
- return result;
- }
-
- protected String getUsersPassword() throws LoginException {
-
- String username = getUsername();
- String password = null;
-
- try {
- password = realm.getUsersPassword(username);
- password = convertRawPassword(password);
- if (logger.isDebugEnabled()) {
- logger.debug("Obtained user password for: " + username);
- }
- } catch (LoginException lex) {
- log.error("Could not retrieve user password for: " + username, lex);
- throw lex;
- } catch (Exception ex) {
- log.error("Could not retrieve user password for: " + username, ex);
- LoginException le = new LoginException("Unknown Exception");
- le.initCause(ex);
- throw le;
- }
-
- return password;
- }
-
- @Override
- public boolean commit() throws LoginException {
- boolean result;
- result = super.commit();
- return result;
- }
-
- @Override
- public boolean abort() throws LoginException {
- boolean result;
- result = super.abort();
- return result;
- }
-
- /** Execute the rolesQuery against the dsJndiName to obtain the roles for
- the authenticated user.
-
- @return Group[] containing the sets of roles
- */
- protected Group[] getRoleSets() throws LoginException {
- String username = getUsername();
-
- Collection<Group> roles = realm.getRoles(username,
- "org.collectionspace.authentication.CSpacePrincipal",
- "org.jboss.security.SimpleGroup");
-
- Collection<Group> tenants = realm.getTenants(username,
- "org.jboss.security.SimpleGroup");
-
- List<Group> all = new ArrayList<Group>();
- all.addAll(roles);
- all.addAll(tenants);
- Group[] roleSets = new Group[all.size()];
- all.toArray(roleSets);
- return roleSets;
- }
-
- /** A hook to allow subclasses to convert a password from the database
- into a plain text string or whatever form is used for matching against
- the user input. It is called from within the getUsersPassword() method.
- @param rawPassword - the password as obtained from the database
- @return the argument rawPassword
- */
- protected String convertRawPassword(String rawPassword) {
- return rawPassword;
- }
-}
package org.collectionspace.authentication.realm;
-import java.security.acl.Group;
-import java.util.Collection;
-import javax.security.auth.login.LoginException;
+import java.util.Set;
+
+import javax.security.auth.login.AccountException;
+
+import org.collectionspace.authentication.CSpaceTenant;
/**
- * CSpaceRealm defines interface for CollectionSpace Realm
+ * Interface for the CollectionSpace realm.
*/
public interface CSpaceRealm {
- /**
- * Obtain password for the given user
+ /**
+ * Retrieves the hashed password used to authenticate a user.
+ *
* @param username
- * @return
- * @throws LoginException
+ * @return the password
+ * @throws AccountNotFoundException if the user is not found
+ * @throws AccountException if the password could not be retrieved
*/
- public String getUsersPassword(String username) throws LoginException;
+ public String getPassword(String username) throws AccountException;
/**
- * Obtain the roles for the authenticated user.
- * @return collection containing the roles
+ * Retrieves the roles for a user.
+ *
+ * @param username
+ * @return a collection of roles
+ * @throws AccountException if the roles could not be retrieved
*/
- public Collection<Group> getRoles(String username, String principalClassName, String groupClassName) throws LoginException;
+ public Set<String> getRoles(String username) throws AccountException;
/**
- * Obtain the tenants for the authenticated user.
- * @return collection containing the tenants
+ * Retrieves the enabled tenants associated with a user.
+ *
+ * @param username
+ * @return a collection of tenants
+ * @throws AccountException if the tenants could not be retrieved
*/
- public Collection<Group> getTenants(String username, String groupClassName) throws LoginException;
+ public Set<CSpaceTenant> getTenants(String username) throws AccountException;
/**
- * Obtain the tenants for the authenticated user, allowing access to disable tenants
- * @return collection containing the tenants
+ * Retrieves the tenants associated with a user, optionally including disabled tenants.
+ *
+ * @param username
+ * @param includeDisabledTenants if true, include disabled tenants
+ * @return a collection of tenants
+ * @throws AccountException if the tenants could not be retrieved
*/
- public Collection<Group> getTenants(String username, String groupClassName, boolean includeDisabledTenants) throws LoginException;
+ public Set<CSpaceTenant> getTenants(String username, boolean includeDisabledTenants) throws AccountException;
}
*/
package org.collectionspace.authentication.realm.db;
-import java.lang.reflect.Constructor;
import java.net.ConnectException;
-import java.security.Principal;
-import java.security.acl.Group;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.Collection;
-import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Set;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
-import javax.security.auth.login.FailedLoginException;
-import javax.security.auth.login.LoginException;
+import javax.security.auth.login.AccountException;
+import javax.security.auth.login.AccountNotFoundException;
import javax.sql.DataSource;
-//import org.apache.commons.logging.Log;
-//import org.apache.commons.logging.LogFactory;
-
-
-
-
-
import org.collectionspace.authentication.AuthN;
import org.collectionspace.authentication.CSpaceTenant;
import org.collectionspace.authentication.realm.CSpaceRealm;
* @author
*/
public class CSpaceDbRealm implements CSpaceRealm {
- private Logger logger = LoggerFactory.getLogger(CSpaceDbRealm.class);
+ private Logger logger = LoggerFactory.getLogger(CSpaceDbRealm.class);
private String datasourceName;
private String principalsQuery;
private String tenantsQueryWithDisabled;
private boolean suspendResume;
- private long maxRetrySeconds = MAX_RETRY_SECONDS;
- private static final int MAX_RETRY_SECONDS = 5;
+ private long maxRetrySeconds = MAX_RETRY_SECONDS;
+ private static final int MAX_RETRY_SECONDS = 5;
private static final String MAX_RETRY_SECONDS_STR = "maxRetrySeconds";
private long delayBetweenAttemptsMillis = DELAY_BETWEEN_ATTEMPTS_MILLISECONDS;
private static final String DELAY_BETWEEN_ATTEMPTS_MILLISECONDS_STR = "delayBetweenAttemptsMillis";
private static final long DELAY_BETWEEN_ATTEMPTS_MILLISECONDS = 200;
- protected void setMaxRetrySeconds(Map options) {
+ protected void setMaxRetrySeconds(Map<String, ?> options) {
Object optionsObj = options.get(MAX_RETRY_SECONDS_STR);
if (optionsObj != null) {
String paramValue = optionsObj.toString();
return this.maxRetrySeconds;
}
- protected void setDelayBetweenAttemptsMillis(Map options) {
+ protected void setDelayBetweenAttemptsMillis(Map<String, ?> options) {
Object optionsObj = options.get(DELAY_BETWEEN_ATTEMPTS_MILLISECONDS_STR);
if (optionsObj != null) {
String paramValue = optionsObj.toString();
* CSpace Database Realm
* @param datasourceName datasource name
*/
- public CSpaceDbRealm(Map options) {
+ public CSpaceDbRealm(Map<String, ?> options) {
datasourceName = (String) options.get("dsJndiName");
if (datasourceName == null) {
datasourceName = "java:/DefaultDS";
}
@Override
- public String getUsersPassword(String username) throws LoginException {
+ public String getPassword(String username) throws AccountException {
String password = null;
Connection conn = null;
if (logger.isDebugEnabled()) {
logger.debug(principalsQuery + " returned no matches from db");
}
- throw new FailedLoginException("No matching username found");
+ throw new AccountNotFoundException("No matching username found");
}
password = rs.getString(1);
} catch (SQLException ex) {
- if (logger.isTraceEnabled() == true) {
- logger.error("Could not open database to read AuthN tables.", ex);
- }
- LoginException le = new LoginException("Authentication query failed: " + ex.getLocalizedMessage());
- le.initCause(ex);
- throw le;
+ if (logger.isTraceEnabled() == true) {
+ logger.error("Could not open database to read AuthN tables.", ex);
+ }
+ AccountException ae = new AccountException("Authentication query failed: " + ex.getLocalizedMessage());
+ ae.initCause(ex);
+ throw ae;
+ } catch (AccountNotFoundException ex) {
+ throw ex;
} catch (Exception ex) {
- LoginException le = new LoginException("Unknown Exception");
- le.initCause(ex);
- throw le;
+ AccountException ae = new AccountException("Unknown Exception");
+ ae.initCause(ex);
+ throw ae;
} finally {
if (rs != null) {
try {
return password;
}
- /**
- * Execute the rolesQuery against the datasourceName to obtain the roles for
- * the authenticated user.
- * @return collection containing the roles
- */
@Override
- public Collection<Group> getRoles(String username, String principalClassName, String groupClassName) throws LoginException {
-
+ public Set<String> getRoles(String username) throws AccountException {
if (logger.isDebugEnabled()) {
logger.debug("getRoleSets using rolesQuery: " + rolesQuery + ", username: " + username);
}
+ Set<String> roles = new LinkedHashSet<String>();
+
Connection conn = null;
- HashMap<String, Group> groupsMap = new HashMap<String, Group>();
PreparedStatement ps = null;
ResultSet rs = null;
if (logger.isDebugEnabled()) {
logger.debug("No roles found");
}
-// if(aslm.getUnauthenticatedIdentity() == null){
-// throw new FailedLoginException("No matching username found in Roles");
-// }
- /* We are running with an unauthenticatedIdentity so create an
- empty Roles set and return.
- */
-
- Group g = createGroup(groupClassName, "Roles");
- groupsMap.put(g.getName(), g);
- return groupsMap.values();
+
+ return roles;
}
do {
String roleName = rs.getString(1);
- String groupName = rs.getString(2);
- if (groupName == null || groupName.length() == 0) {
- groupName = "Roles";
- }
-
- Group group = (Group) groupsMap.get(groupName);
- if (group == null) {
- group = createGroup(groupClassName, groupName);
- groupsMap.put(groupName, group);
- }
-
- try {
- Principal p = createPrincipal(principalClassName, roleName);
- if (logger.isDebugEnabled()) {
- logger.debug("Assign user to role " + roleName);
- }
-
- group.addMember(p);
- } catch (Exception e) {
- logger.error("Failed to create principal: " + roleName + " " + e.toString());
- }
-
+ roles.add(roleName);
+
} while (rs.next());
} catch (SQLException ex) {
- LoginException le = new LoginException("Query failed");
- le.initCause(ex);
- throw le;
+ AccountException ae = new AccountException("Query failed");
+ ae.initCause(ex);
+ throw ae;
} catch (Exception e) {
- LoginException le = new LoginException("unknown exception");
- le.initCause(e);
- throw le;
+ AccountException ae = new AccountException("unknown exception");
+ ae.initCause(e);
+ throw ae;
} finally {
if (rs != null) {
try {
}
- return groupsMap.values();
+ return roles;
}
@Override
- public Collection<Group> getTenants(String username, String groupClassName) throws LoginException {
- return getTenants(username, groupClassName, false);
+ public Set<CSpaceTenant> getTenants(String username) throws AccountException {
+ return getTenants(username, false);
}
private boolean userIsTenantManager(Connection conn, String username) {
- String acctQuery = "SELECT csid FROM accounts_common WHERE userid=?";
+ String acctQuery = "SELECT csid FROM accounts_common WHERE userid=?";
PreparedStatement ps = null;
ResultSet rs = null;
boolean accountIsTenantManager = false;
/**
* Execute the tenantsQuery against the datasourceName to obtain the tenants for
* the authenticated user.
- * @return collection containing the roles
+ * @return set containing the roles
*/
@Override
- public Collection<Group> getTenants(String username, String groupClassName, boolean includeDisabledTenants) throws LoginException {
+ public Set<CSpaceTenant> getTenants(String username, boolean includeDisabledTenants) throws AccountException {
String tenantsQuery = getTenantQuery(includeDisabledTenants);
logger.debug("getTenants using tenantsQuery: " + tenantsQuery + ", username: " + username);
}
+ Set<CSpaceTenant> tenants = new LinkedHashSet<CSpaceTenant>();
+
Connection conn = null;
- HashMap<String, Group> groupsMap = new HashMap<String, Group>();
PreparedStatement ps = null;
ResultSet rs = null;
- final String defaultGroupName = "Tenants";
try {
conn = getConnection();
}
rs = ps.executeQuery();
if (rs.next() == false) {
- Group group = (Group) groupsMap.get(defaultGroupName);
- if (group == null) {
- group = createGroup(groupClassName, defaultGroupName);
- groupsMap.put(defaultGroupName, group);
- }
- // Check for the tenantManager
- if(userIsTenantManager(conn, username)) {
- if (logger.isDebugEnabled()) {
- logger.debug("GetTenants called with tenantManager - synthesizing the pseudo-tenant");
- }
- try {
- Principal p = createTenant("PseudoTenant", AuthN.TENANT_MANAGER_ACCT_ID);
- if (logger.isDebugEnabled()) {
- logger.debug("Assign tenantManager to tenant " + AuthN.TENANT_MANAGER_ACCT_ID);
- }
- group.addMember(p);
- } catch (Exception e) {
- logger.error("Failed to create pseudo-tenant: " + e.toString());
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("No tenants found");
- }
- // We are running with an unauthenticatedIdentity so return an
- // empty Tenants set.
- // FIXME should this be allowed?
- }
- return groupsMap.values();
+ // Check for the tenantManager
+ if(userIsTenantManager(conn, username)) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("GetTenants called with tenantManager - synthesizing the pseudo-tenant");
+ }
+
+ tenants.add(new CSpaceTenant(AuthN.TENANT_MANAGER_ACCT_ID, "PseudoTenant"));
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("No tenants found");
+ }
+ // We are running with an unauthenticatedIdentity so return an
+ // empty Tenants set.
+ // FIXME should this be allowed?
+ }
+
+ return tenants;
}
do {
String tenantId = rs.getString(1);
String tenantName = rs.getString(2);
- String groupName = rs.getString(3);
- if (groupName == null || groupName.length() == 0) {
- groupName = defaultGroupName;
- }
-
- Group group = (Group) groupsMap.get(groupName);
- if (group == null) {
- group = createGroup(groupClassName, groupName);
- groupsMap.put(groupName, group);
- }
-
- try {
- Principal p = createTenant(tenantName, tenantId);
- if (logger.isDebugEnabled()) {
- logger.debug("Assign user to tenant " + tenantName);
- }
- group.addMember(p);
- } catch (Exception e) {
- logger.error("Failed to create tenant: " + tenantName + " " + e.toString());
- }
+ tenants.add(new CSpaceTenant(tenantId, tenantName));
} while (rs.next());
} catch (SQLException ex) {
- LoginException le = new LoginException("Query failed");
- le.initCause(ex);
- throw le;
+ AccountException ae = new AccountException("Query failed");
+ ae.initCause(ex);
+ throw ae;
} catch (Exception e) {
- LoginException le = new LoginException("unknown exception");
- le.initCause(e);
- throw le;
+ AccountException ae = new AccountException("unknown exception");
+ ae.initCause(e);
+ throw ae;
} finally {
if (rs != null) {
try {
} catch (Exception ex) {
}
}
-
}
- return groupsMap.values();
- }
-
- private CSpaceTenant createTenant(String name, String id) throws Exception {
- return new CSpaceTenant(name, id);
- }
-
- private Group createGroup(String groupClassName, String name) throws Exception {
- return (Group) createPrincipal(groupClassName, name);
- }
-
- private Principal createPrincipal(String principalClassName, String name) throws Exception {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- Class clazz = loader.loadClass(principalClassName);
- Class[] ctorSig = {String.class};
- Constructor ctor = clazz.getConstructor(ctorSig);
- Object[] ctorArgs = {name};
- Principal p = (Principal) ctor.newInstance(ctorArgs);
- return p;
+ return tenants;
}
/*
/*
* Don't call this method directly. Instead, use the getConnection() method that take no arguments.
*/
- private Connection getConnection(String dataSourceName) throws LoginException, SQLException {
+ private Connection getConnection(String dataSourceName) throws AccountException, SQLException {
InitialContext ctx = null;
Connection conn = null;
DataSource ds = null;
return conn;
} catch (NamingException ex) {
- LoginException le = new LoginException("Error looking up DataSource from: " + dataSourceName);
- le.initCause(ex);
- throw le;
+ AccountException ae = new AccountException("Error looking up DataSource from: " + dataSourceName);
+ ae.initCause(ex);
+ throw ae;
} finally {
if (ctx != null) {
try {
*/
package org.collectionspace.authentication.spi;
-import javax.security.auth.Subject;
+import java.util.List;
+
import org.collectionspace.authentication.CSpaceTenant;
+import org.collectionspace.authentication.CSpaceUser;
/**
- * Utilities to be used by Services runtime to interface with authentication service
- * @author
+ * Utilities for accessing the authentication context.
*/
-public abstract class AuthNContext {
-
- public static final String ANONYMOUS_USER = "anonymous";
- public static final String ANONYMOUS_TENANT_ID = "-1";
- public static final String ANONYMOUS_TENANT_NAME = ANONYMOUS_USER;
+public interface AuthNContext {
+
+ public static final String ANONYMOUS_USER = "anonymous";
+ public static final String ANONYMOUS_TENANT_ID = "-1";
+ public static final String ANONYMOUS_TENANT_NAME = ANONYMOUS_USER;
public static final String SPRING_ADMIN_USER = "SPRING_ADMIN";
public static final String TENANT_ID_QUERY_PARAM = "tid";
public static final String TENANT_ID_PATH_PARAM = "tenantId";
-
/**
- * getUserId returns authenticated user id
- * @return
+ * Returns the username of the authenticated user.
+ *
+ * @return the username
*/
- public abstract String getUserId();
+ public String getUserId();
/**
- * getTenantIds get tenant ids from the tenant context associated with the
- * security context
- * @return
+ * Returns the authenticated user.
+ *
+ * @return the user
*/
- public abstract String[] getTenantIds();
+ public CSpaceUser getUser();
/**
- * getCurrentTenantId get id of the tenant associated with the authenticated user
- * @return
+ * Returns the id of the primary tenant associated with the authenticated user.
+ *
+ * @return the tenant id
*/
- public abstract String getCurrentTenantId();
+ public String getCurrentTenantId();
/**
- * getCurrentTenantName get name of the tenant associated with the authenticated user
- * @return
+ * Returns the name of the primary tenant associated with the authenticated user.
+ *
+ * @return the tenant name
+ */
+ public String getCurrentTenantName();
+
+ /**
+ * Returns the primary tenant associated with the authenticated user.
+ *
+ * @return the tenant
*/
- public abstract String getCurrentTenantName();
+ public CSpaceTenant getCurrentTenant();
/**
- * getTenants get tenant context associated with the security context
- * @see CSpaceTenant
- * @return
+ * Returns all tenants associated with the authenticated user.
+ *
+ * @return a list of tenants
*/
- public abstract CSpaceTenant[] getTenants();
+ public List<CSpaceTenant> getTenants();
/**
- * getSubject retrieves security context as Subject
- * @see javax.security.auth.Subject
+ * Returns the ids of all tenants associated with the authenticated user.
+ *
+ * @return a list of tenant ids
*/
- public abstract Subject getSubject();
+ public List<String> getTenantIds();
}
+++ /dev/null
-/**
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
-
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
-
- * Copyright 2009 University of California at Berkeley
-
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
-
- * You may obtain a copy of the ECL 2.0 License at
-
- * https://source.collectionspace.org/collection-space/LICENSE.txt
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *//**
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
-
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
-
- * Copyright 2009 University of California at Berkeley
-
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
-
- * You may obtain a copy of the ECL 2.0 License at
-
- * https://source.collectionspace.org/collection-space/LICENSE.txt
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.collectionspace.authentication.spring;
-
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.springframework.security.authentication.jaas.AuthorityGranter;
-
-/**
- * CSpaceAuthorityGranter maps a given prinicpal to role names
- * @author
- */
-public class CSpaceAuthorityGranter implements AuthorityGranter {
-
- public Set<String> grant(Principal principal) {
- Set<String> authorities = new HashSet<String>();
- if (principal instanceof Group) {
- Group g = (Group) principal;
- Enumeration<? extends Principal> members = g.members();
- while (members.hasMoreElements()) {
- Principal p = (Principal) members.nextElement();
- authorities.add(p.getName());
- }
- } else {
- authorities.add(principal.getName());
- }
- return authorities;
- }
-}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
package org.collectionspace.authentication.spring;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import javax.security.auth.login.AccountException;
+import javax.security.auth.login.AccountNotFoundException;
-import org.springframework.dao.DataAccessException;
+import org.collectionspace.authentication.CSpaceTenant;
+import org.collectionspace.authentication.CSpaceUser;
+import org.collectionspace.authentication.realm.CSpaceRealm;
+import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
/**
- * A CollectionSpace UserDetailsService for spring
- * mockup code to cheat spring config reader...not used by Spring JaasAuthenticationProvider
+ * A Spring UserDetailsService for CollectionSpace.
*/
-//FIXME remove test/mockup code
public class CSpaceUserDetailsService implements UserDetailsService {
+ private CSpaceRealm realm = null;
- private Map<String, User> users = new HashMap<String, User>();
- private List<GrantedAuthority> auths = AuthorityUtils.createAuthorityList("ROLE_USER");
-
- public CSpaceUserDetailsService() {
- users.put("test", new User("test", "", true, true, true, true, auths));
+ public CSpaceUserDetailsService(CSpaceRealm realm) {
+ this.realm = realm;
}
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
- if (users.get(username) == null) {
- throw new UsernameNotFoundException("User not found: " + username);
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ String password = null;
+ Set<CSpaceTenant> tenants = null;
+ Set<GrantedAuthority> grantedAuthorities = null;
+
+ try {
+ password = realm.getPassword(username);
+ tenants = getTenants(username);
+ grantedAuthorities = getAuthorities(username);
}
-
- return users.get(username);
+ catch (AccountNotFoundException e) {
+ throw new UsernameNotFoundException(e.getMessage(), e);
+ }
+ catch (AccountException e) {
+ throw new AuthenticationServiceException(e.getMessage(), e);
+ }
+
+ return
+ new CSpaceUser(
+ username,
+ password,
+ tenants,
+ grantedAuthorities);
+ }
+
+ protected Set<GrantedAuthority> getAuthorities(String username) throws AccountException {
+ Set<String> roles = realm.getRoles(username);
+ Set<GrantedAuthority> authorities = new LinkedHashSet<GrantedAuthority>(roles.size());
+
+ for (String role : roles) {
+ authorities.add(new SimpleGrantedAuthority(role));
+ }
+
+ return authorities;
+ }
+
+ protected Set<CSpaceTenant> getTenants(String username) throws AccountException {
+ Set<CSpaceTenant> tenants = realm.getTenants(username);
+
+ return tenants;
}
}
package org.collectionspace.authentication.spring;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.List;
-import java.util.Set;
-
-import java.security.acl.Group;
-import javax.security.auth.Subject;
import org.collectionspace.authentication.CSpaceTenant;
+import org.collectionspace.authentication.CSpaceUser;
import org.collectionspace.authentication.spi.AuthNContext;
-
-import org.springframework.security.authentication.jaas.JaasAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
/**
- * SpringAuthNContext provides utilities to CSpace services runtime
- * @author
+ * Utilities for accessing the Spring Security authentication context.
*/
-final public class SpringAuthNContext extends AuthNContext {
- //private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
+public class SpringAuthNContext implements AuthNContext {
+ /**
+ * Returns the username of the authenticated user.
+ *
+ * @return the username
+ */
public String getUserId() {
- String result = ANONYMOUS_USER;
-
+ String result = ANONYMOUS_USER;
+
Authentication authToken = SecurityContextHolder.getContext().getAuthentication();
+
if (authToken != null) {
- result = authToken.getName();
- }
+ result = authToken.getName();
+ }
return result;
}
/**
- * retrieve tenant ids from Jaas LoginContext
- * @return
+ * Returns the authenticated user.
+ *
+ * @return the user
*/
- @Override
- public String[] getTenantIds() {
-
- ArrayList<String> tenantList = new ArrayList<String>();
- CSpaceTenant[] tenants = getTenants();
- for (CSpaceTenant tenant : tenants) {
- tenantList.add(tenant.getId());
- }
- return tenantList.toArray(new String[0]);
+ public CSpaceUser getUser() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ Object principal = authentication.getPrincipal();
+ CSpaceUser user = (CSpaceUser) principal;
+
+ return user;
}
- @Override
+ /**
+ * Returns the id of the primary tenant associated with the authenticated user.
+ *
+ * @return the tenant id
+ */
public String getCurrentTenantId() {
- String result = ANONYMOUS_TENANT_ID;
-
- String userId = getUserId();
- if (userId.equals(ANONYMOUS_USER) == false && userId.equals(SPRING_ADMIN_USER) == false) {
- String[] tenantIds = getTenantIds();
- if (tenantIds.length < 1) {
- throw new IllegalStateException("No tenant associated with user=" + getUserId());
- }
- result = getTenantIds()[0];
- }
-
- return result;
- }
-
- public CSpaceTenant[] getTenants() {
- List<CSpaceTenant> tenants = new ArrayList<CSpaceTenant>();
- Subject caller = getSubject();
- if (caller == null) {
- if (getUserId().equals(SPRING_ADMIN_USER) == false) {
- String msg = String.format("Could not find Subject in SpringAuthNContext for user '%s'!", getUserId());
- System.err.println(msg);
- }
- return tenants.toArray(new CSpaceTenant[0]);
- }
+ String username = getUserId();
- Set<Group> groups = null;
- groups = caller.getPrincipals(Group.class);
- if (groups != null && groups.size() == 0) {
- String msg = "no role(s)/tenant(s) found!";
- //TODO: find out why no roles / tenants found
- //FIXME: if logger is loaded when authn comes up, use it
- //logger.warn(msg);
- System.err.println(msg);
- return tenants.toArray(new CSpaceTenant[0]);
- }
- for (Group g : groups) {
- if ("Tenants".equals(g.getName())) {
- Enumeration members = g.members();
- while (members.hasMoreElements()) {
- CSpaceTenant tenant = (CSpaceTenant) members.nextElement();
- tenants.add(tenant);
- //FIXME: if logger is loaded when authn comes up, use it
-// if (logger.isDebugEnabled()) {
-// logger.debug("found tenant id=" + tenant.getId()
-// + " name=" + tenant.getName());
-// }
- }
- }
+ if (username.equals(ANONYMOUS_USER) || username.equals(SPRING_ADMIN_USER)) {
+ return ANONYMOUS_TENANT_ID;
}
- return tenants.toArray(new CSpaceTenant[0]);
+
+ return getCurrentTenant().getId();
}
- @Override
+ /**
+ * Returns the name of the primary tenant associated with the authenticated user.
+ *
+ * @return the tenant name
+ */
public String getCurrentTenantName() {
- String result = ANONYMOUS_TENANT_NAME;
-
- if (getUserId().equals(ANONYMOUS_USER) == false) {
- CSpaceTenant[] tenants = getTenants();
- if (tenants.length < 1) {
- throw new IllegalStateException("No tenant associated with user=" + getUserId());
+ if (getUserId().equals(ANONYMOUS_USER)) {
+ return ANONYMOUS_TENANT_NAME;
}
- result = getTenants()[0].getName();
+
+ return getCurrentTenant().getName();
}
-
- return result;
+
+ /**
+ * Returns the primary tenant associated with the authenticated user.
+ *
+ * @return the tenant
+ */
+ public CSpaceTenant getCurrentTenant() {
+ List<CSpaceTenant> tenants = getTenants();
+
+ if (tenants.size() < 1) {
+ throw new IllegalStateException("No tenant associated with user " + getUserId());
+ }
+
+ return tenants.get(0);
}
- public Subject getSubject() {
- Subject caller = null;
- //if Spring was not used....
- //caller = (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY);
+ /**
+ * Returns all tenants associated with the authenticated user.
+ *
+ * @return a list of tenants
+ */
+ public List<CSpaceTenant> getTenants() {
+ return new ArrayList<CSpaceTenant>(getUser().getTenants());
+ }
- //FIXME the follow call should be protected with a privileged action
- //and must only be available to users with super privileges
- //Spring does not offer any easy mechanism
- //It is a bad idea to ship with a kernel user...kernel user should be
- //created at startup time perhaps and used it here
- Authentication authToken = SecurityContextHolder.getContext().getAuthentication();
- JaasAuthenticationToken jaasToken = null;
- if (authToken instanceof JaasAuthenticationToken) {
- jaasToken = (JaasAuthenticationToken) authToken;
- caller = (Subject) jaasToken.getLoginContext().getSubject();
+ /**
+ * Returns the ids of all tenants associated with the authenticated user.
+ *
+ * @return a list of tenant ids
+ */
+ public List<String> getTenantIds() {
+ List<CSpaceTenant> tenants = getTenants();
+ List<String> tenantIds = new ArrayList<String>(tenants.size());
+
+ for (CSpaceTenant tenant : tenants) {
+ tenantIds.add(tenant.getId());
}
- return caller;
+
+ return tenantIds;
}
}
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
- <head>
- <!--
- This document is a part of the source code and related artifacts
- for CollectionSpace, an open source collections management system
- for museums and related institutions:
-
- http://www.collectionspace.org
- http://wiki.collectionspace.org
-
- Copyright 2010 University of California at Berkeley
-
- Licensed under the Educational Community License (ECL), Version 2.0.
- You may not use this file except in compliance with this License.
-
- You may obtain a copy of the ECL 2.0 License at
-
- https://source.collectionspace.org/collection-space/LICENSE.txt
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
- </head>
- <body bgcolor="white">
-
- Provides classes and interfaces for CollectionSpace Authorization Service
- Service Provider Interfaces (SPI).
-
- <h2>Package Specification</h2>
-
-
- <ul>
- <li><a href=""></a>
- </ul>
-
- <h2>Related Documentation</h2>
-
- For overviews, tutorials, examples, guides, and tool documentation, please see:
- <ul>
- <li><a href=""></a>
- </ul>
-
- <!-- Put @see and @since tags down here. -->
-
- </body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
- <head>
- <!--
- This document is a part of the source code and related artifacts
- for CollectionSpace, an open source collections management system
- for museums and related institutions:
-
- http://www.collectionspace.org
- http://wiki.collectionspace.org
-
- Copyright 2010 University of California at Berkeley
-
- Licensed under the Educational Community License (ECL), Version 2.0.
- You may not use this file except in compliance with this License.
-
- You may obtain a copy of the ECL 2.0 License at
-
- https://source.collectionspace.org/collection-space/LICENSE.txt
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
- </head>
- <body bgcolor="white">
-
-
- Provides classes and interfaces for CollectionSpace Authorization Service.
- Interfaces include both Service Provider Interfaces (SPI) and Application
- Programming Interfaces (API)
-
-
- <h2>Package Specification</h2>
-
-
- <ul>
- <li><a href=""></a>
- </ul>
-
- <h2>Related Documentation</h2>
-
- For overviews, tutorials, examples, guides, and tool documentation, please see:
- <ul>
- <li><a href=""></a>
- </ul>
-
- <!-- Put @see and @since tags down here. -->
-
- </body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
- <head>
- <!--
- This document is a part of the source code and related artifacts
- for CollectionSpace, an open source collections management system
- for museums and related institutions:
-
- http://www.collectionspace.org
- http://wiki.collectionspace.org
-
- Copyright 2010 University of California at Berkeley
-
- Licensed under the Educational Community License (ECL), Version 2.0.
- You may not use this file except in compliance with this License.
-
- You may obtain a copy of the ECL 2.0 License at
-
- https://source.collectionspace.org/collection-space/LICENSE.txt
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
- </head>
- <body bgcolor="white">
-
- Provides classes and interfaces for Spring provider for the CollectionSpace
- Authorization Service.
-
- <h2>Package Specification</h2>
-
-
- <ul>
- <li><a href=""></a>
- </ul>
-
- <h2>Related Documentation</h2>
-
- For overviews, tutorials, examples, guides, and tool documentation, please see:
- <ul>
- <li><a href=""></a>
- </ul>
-
- <!-- Put @see and @since tags down here. -->
-
- </body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
- <head>
- <!--
- This document is a part of the source code and related artifacts
- for CollectionSpace, an open source collections management system
- for museums and related institutions:
-
- http://www.collectionspace.org
- http://wiki.collectionspace.org
-
- Copyright 2010 University of California at Berkeley
-
- Licensed under the Educational Community License (ECL), Version 2.0.
- You may not use this file except in compliance with this License.
-
- You may obtain a copy of the ECL 2.0 License at
-
- https://source.collectionspace.org/collection-space/LICENSE.txt
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
- </head>
- <body bgcolor="white">
-
- Provides classes and interfaces for Spring provider for the CollectionSpace
- Authorization Service.
-
- <h2>Package Specification</h2>
-
-
- <ul>
- <li><a href=""></a>
- </ul>
-
- <h2>Related Documentation</h2>
-
- For overviews, tutorials, examples, guides, and tool documentation, please see:
- <ul>
- <li><a href=""></a>
- </ul>
-
- <!-- Put @see and @since tags down here. -->
-
- </body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
- <HEAD>
- <!--
- This document is a part of the source code and related artifacts
- for CollectionSpace, an open source collections management system
- for museums and related institutions:
-
- http://www.collectionspace.org
- http://wiki.collectionspace.org
-
- Copyright 2010 University of California at Berkeley
-
- Licensed under the Educational Community License (ECL), Version 2.0.
- You may not use this file except in compliance with this License.
-
- You may obtain a copy of the ECL 2.0 License at
-
- https://source.collectionspace.org/collection-space/LICENSE.txt
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
- <TITLE>Authorization Service Overview</TITLE>
- </HEAD>
- <BODY>
- This document describes the source code of the CollectionSpace
- Authorization Service.
- <br/>
- It includes the classes and interfaces for the following.
- <br/>
- - Java XML bindings for role, permission, and relationships
- - Service side source including APIs, SPIs and provider implementations
- </BODY>
-</HTML>
\ No newline at end of file
import org.hibernate.exception.ConstraintViolationException;
-import org.jboss.security.SimpleGroup;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.authentication.jaas.JaasGrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
}
private void login() {
- //GrantedAuthority cspace_admin = new JaasGrantedAuthority("ROLE_ADMINISTRATOR", new SimpleGroup("Role"));
- GrantedAuthority spring_security_admin = new JaasGrantedAuthority("ROLE_SPRING_ADMIN", new SimpleGroup("Role")); //NOTE: Must match with value in applicationContext-authorization-test.xml (aka SPRING_SECURITY_METADATA)
+ //GrantedAuthority cspace_admin = new SimpleGrantedAuthority("ROLE_ADMINISTRATOR");
+ GrantedAuthority spring_security_admin = new SimpleGrantedAuthority("ROLE_SPRING_ADMIN"); //NOTE: Must match with value in applicationContext-authorization-test.xml (aka SPRING_SECURITY_METADATA)
HashSet<GrantedAuthority> gauths = new HashSet<GrantedAuthority>();
//gauths.add(cspace_admin);
gauths.add(spring_security_admin);
<bean id="aclAuthorizationStrategy" class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<list>
- <bean class="org.springframework.security.authentication.jaas.JaasGrantedAuthority">
+ <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<constructor-arg value="ROLE_SPRING_ADMIN"/>
- <constructor-arg>
- <bean class="org.jboss.security.SimpleGroup">
- <constructor-arg value="Role"/>
- </bean>
- </constructor-arg>
</bean>
</list>
</constructor-arg>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.collectionspace.services.authorization.spi.CSpaceAuthorizationProvider;
-import org.jboss.security.SimpleGroup;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.authentication.jaas.JaasGrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
/**
public void login() {
String user = "SPRING_ADMIN";
String password = "SPRING_ADMIN";
- GrantedAuthority spring_security_admin = new JaasGrantedAuthority("ROLE_SPRING_ADMIN", new SimpleGroup("Role")); //NOTE: Must match with value in applicationContext-authorization-test.xml (aka SPRING_SECURITY_METADATA)
+ GrantedAuthority spring_security_admin = new SimpleGrantedAuthority("ROLE_SPRING_ADMIN"); //NOTE: Must match with value in applicationContext-authorization-test.xml (aka SPRING_SECURITY_METADATA)
HashSet<GrantedAuthority> gauths = new HashSet<GrantedAuthority>();
gauths.add(spring_security_admin);
Authentication authRequest = new UsernamePasswordAuthenticationToken(user, password, gauths);
<bean id="aclAuthorizationStrategy" class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<list>
- <bean class="org.springframework.security.authentication.jaas.JaasGrantedAuthority">
+ <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<constructor-arg value="ROLE_SPRING_ADMIN"/>
- <constructor-arg>
- <bean class="org.jboss.security.SimpleGroup">
- <constructor-arg value="Role"/>
- </bean>
- </constructor-arg>
</bean>
</list>
</constructor-arg>
<target name="undeploy_spring"
description="undeploy spring binaries from ${jee.server.cspace}">
<delete>
+ <fileset dir="${jee.server.cspace}/lib" includes="aopalliance-*.jar"/>
+ <fileset dir="${jee.server.cspace}/lib" includes="commons-lang3-*.jar"/>
+ <fileset dir="${jee.server.cspace}/lib" includes="ehcache-*.jar"/>
<fileset dir="${jee.server.cspace}/lib" includes="org.springframework.*.jar"/>
<fileset dir="${jee.server.cspace}/lib" includes="spring-*.jar"/>
- <fileset dir="${jee.server.cspace}/lib" includes="ehcache-*.jar"/>
</delete>
</target>