support schema per tenant multi-tenancy. basic auth security filter is extended to detect tenant-id header on request, verify tenant id is valid and then use provided credentials to authenticate user details against users on the tenant specific schema.

This commit is contained in:
Keith Woodlock
2012-07-13 18:05:43 +01:00
parent 816d3decf9
commit 15f0fc4677
34 changed files with 399 additions and 195 deletions
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="jpa-pu" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
@@ -7,7 +10,7 @@
<!--
<property name="hibernate.hbm2ddl.auto" value="update"/>
-->
<property name="hibernate.jdbc.batch_size" value="200"/>
<property name="hibernate.jdbc.batch_size" value="100"/>
<property name="hibernate.order_inserts" value="true"/>
</properties>
</persistence-unit>
@@ -3,12 +3,10 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
@@ -17,8 +15,8 @@
<tx:annotation-driven />
<context:component-scan base-package="org.mifosng.platform.rest, org.mifosng.platform.security, org.mifosng.platform.infrastructure,
org.mifosng.platform.*.domain, org.mifosng.platform, org.mifosng.demo">
<context:component-scan base-package="org.mifosng.platform.security, org.mifosng.platform.infrastructure,
org.mifosng.platform.*.domain, org.mifosng.platform">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</context:component-scan>
@@ -7,7 +7,7 @@
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="dataSource" ref="tenantAwareDataSource" />
<property name="persistenceUnitName" value="jpa-pu" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
@@ -23,14 +23,5 @@
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<jee:jndi-lookup jndi-name="java:comp/env/jdbc/mifosng" id="dataSource" />
<!--
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mifosngprovider" />
<property name="username" value="root" />
<property name="password" value="mysql" />
</bean>
-->
<jee:jndi-lookup jndi-name="java:comp/env/jdbc/mifosplatform-tenants" id="tenantDataSourceJndi" />
</beans>
@@ -7,15 +7,25 @@
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<http create-session="stateless" use-expressions="true" pattern="/api/**" realm="Mifos Platform API">
<intercept-url pattern="/api/*/authentication" access="permitAll" method="POST" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="GET" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="POST" requires-channel="https"/>
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="PUT" requires-channel="https"/>
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="DELETE" requires-channel="https"/>
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="HEAD" requires-channel="https"/>
<http-basic />
<http create-session="stateless" use-expressions="true" pattern="/api/**" entry-point-ref="basicAuthenticationEntryPoint">
<intercept-url pattern="/api/*/authentication" access="permitAll" method="POST" requires-channel="http" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="GET" requires-channel="http" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="POST" requires-channel="http"/>
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="PUT" requires-channel="http"/>
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="DELETE" requires-channel="http"/>
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" method="HEAD" requires-channel="http"/>
<custom-filter after="SECURITY_CONTEXT_FILTER" ref="basicAuthenticationProcessingFilter" />
</http>
<beans:bean id="basicAuthenticationEntryPoint" class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<beans:property name="realmName" value="Mifos Platform API" />
</beans:bean>
<beans:bean id="basicAuthenticationProcessingFilter" class="org.mifosng.platform.infrastructure.TenantAwareBasicAuthenticationFilter">
<beans:constructor-arg ref="authenticationManager" />
<beans:constructor-arg ref="basicAuthenticationEntryPoint" />
</beans:bean>
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="256"/>
@@ -25,8 +35,6 @@
<beans:property name="userPropertyToUse" value="id"/>
</beans:bean>
<beans:bean id="userDetailsService" class="org.mifosng.platform.security.PlatformUserDetailsServiceImpl" />
<beans:bean id="customAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
@@ -7,7 +7,7 @@
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${catalina.base}/logs/mifosng-provider.log</file>
<file>${catalina.home}/logs/mifos-platform.log</file>
<append>true</append>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->