finish up work on moving backend into stateless server with resource-oriented api using basic auth for securing api calls.

This commit is contained in:
Keith Woodlock
2012-05-17 15:11:49 +01:00
parent 45965a3f50
commit 93678bf9ce
52 changed files with 150 additions and 2902 deletions
@@ -17,7 +17,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.rest, org.mifosng.platform.security, org.mifosng.platform.infrastructure,
org.mifosng.platform.*.domain, org.mifosng.platform, org.mifosng.demo">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</context:component-scan>
@@ -27,28 +28,6 @@
<jpa:repositories base-package="org.mifosng.platform.*.domain" />
<import resource="infrastructure.xml" />
<!--
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongo" />
<constructor-arg value="test" />
</bean>
<bean class="org.springframework.data.mongodb.core.MongoExceptionTranslator" />
<mongo:mongo id="mongo" host="localhost" port="27017" />
<mongo:repositories base-package="org.mifosng.platform.*.mongo" />
<bean class="org.springframework.data.persistence.document.mongodb.MongoDocumentBacking" factory-method="aspectOf">
<property name="changeSetPersister" ref="mongoChangeSetPersister"/>
</bean>
<bean id="mongoChangeSetPersister" class="org.springframework.data.persistence.document.mongodb.MongoChangeSetPersister">
<property name="mongoTemplate" ref="mongoTemplate"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
-->
<import resource="securityContext.xml" />
</beans>
@@ -1,138 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/security/oauth
http://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd">
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<sec:filter-chain pattern="/resources/**" filters="none" />
<sec:filter-chain pattern="/api/open/**" filters="none" />
<sec:filter-chain pattern="/api/v1/**" filters="none" />
<sec:filter-chain pattern="/**" filters="populateSecurityContextFilter, customAuthenticationFilter,
oauthRequestTokenFilter, oauthUserAuthorizationFilter, oauthAccessTokenFilter, oauthProtectedResourceFilter,
filterSecurityInterceptor" />
</list>
</constructor-arg>
</bean>
<bean id="oauthProviderTokenServicesDelegate" class="org.mifosng.oauth.RemovableInMemoryProviderTokenServices" />
<bean id="tokenServices" class="org.mifosng.oauth.CustomTokenServices">
<constructor-arg ref="oauthProviderTokenServicesDelegate" />
</bean>
<bean id="roleBasedAuthenticationSuccessHandler" class="org.mifosng.platform.infrastructure.FirstTimeLoginDetectionAuthenticationSuccessHandler">
<constructor-arg ref="tokenServices" />
<property name="defaultTargetUrl" value="/home" />
<property name="alwaysUseDefaultTargetUrl" value="true" />
<property name="firstTimeLoginUrl" value="/firsttimelogin" />
</bean>
<bean id="customAuthenticationFalureHandler" class="org.mifosng.platform.infrastructure.CustomAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login" />
</bean>
<http create-session="stateless" use-expressions="true" pattern="/api/**">
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" />
<http-basic />
</http>
<bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy" />
<bean id="customAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="roleBasedAuthenticationSuccessHandler" />
<property name="authenticationFailureHandler" ref="customAuthenticationFalureHandler" />
<property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy" />
</bean>
<bean id="populateSecurityContextFilter" class="org.mifosng.oauth.OAuthParametersAwareSecurityContextPerRequestFilter">
<constructor-arg ref="tokenServices" />
</bean>
<bean id="oauthConsumerDetailsService" class="org.mifosng.oauth.MifosNgConsumerDetailsService" />
<bean id="oauthRequestTokenFilter" class="org.springframework.security.oauth.provider.filter.UnauthenticatedRequestTokenProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/request_token" />
<property name="tokenServices" ref="tokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="customAuthenticationProvider" />
</sec:authentication-manager>
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<constructor-arg value="256"/>
</bean>
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="256"/>
</beans:bean>
<bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<property name="userPropertyToUse" value="id"/>
</bean>
<bean id="userDetailsService" class="org.mifosng.platform.security.PlatformUserDetailsServiceImpl" />
<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<beans:property name="userPropertyToUse" value="id"/>
</beans:bean>
<beans:bean id="userDetailsService" class="org.mifosng.platform.security.PlatformUserDetailsServiceImpl" />
<bean id="customAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder" ref="passwordEncoder" />
<property name="saltSource" ref="saltSource" />
</bean>
<bean id="oauthRandomValueVerifierServices" class="org.springframework.security.oauth.provider.verifier.RandomValueVerifierServices" />
<bean id="oauthAuthorizationSuccessHandler" class="org.springframework.security.oauth.provider.filter.UserAuthorizationSuccessfulAuthenticationHandler" />
<bean id="oauthUserAuthorizationFilter" class="org.springframework.security.oauth.provider.filter.UserAuthorizationProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/authorize" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="tokenServices" ref="tokenServices" />
<property name="verifierServices" ref="oauthRandomValueVerifierServices" />
<property name="authenticationSuccessHandler" ref="oauthAuthorizationSuccessHandler" />
</bean>
<bean id="oauthAccessTokenFilter" class="org.springframework.security.oauth.provider.filter.AccessTokenProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/access_token" />
<property name="tokenServices" ref="tokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="oauthProtectedResourceFilter" class="org.mifosng.oauth.CustomProtectedResourceProcessingFilter">
<property name="tokenServices" ref="tokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
<bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
</list>
</property>
</bean>
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="securityMetadataSource">
<sec:filter-security-metadata-source use-expressions="true">
<sec:intercept-url pattern="/login" access="isAnonymous()" />
<sec:intercept-url pattern="/logout" access="isAnonymous()" />
<sec:intercept-url pattern="/signup" access="isAnonymous()" />
<sec:intercept-url pattern="/pentahoreport*" access="isAnonymous()" />
<sec:intercept-url pattern="/exportcsv*" access="isAnonymous()" />
<sec:intercept-url pattern="/oauth/authorize" access="isAnonymous()" />
<sec:intercept-url pattern="/oauth/access_token" access="isAnonymous()" />
<sec:intercept-url pattern="/oauth/confirm_access*" access="isAnonymous() or isFullyAuthenticated()" />
<sec:intercept-url pattern="/api/protected/**" access="isFullyAuthenticated()" />
<sec:intercept-url pattern="/**" access="isFullyAuthenticated()" />
</sec:filter-security-metadata-source>
</property>
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
</bean>
</beans>
<beans:bean id="customAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
<beans:property name="saltSource" ref="saltSource" />
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
</beans:beans>
@@ -1,241 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:oauth="http://www.springframework.org/schema/security/oauth"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security/oauth
http://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd">
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="256"/>
</beans:bean>
<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<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" />
<beans:property name="saltSource" ref="saltSource" />
</beans:bean>
<beans:bean id="roleBasedAuthenticationSuccessHandler" class="org.mifosng.platform.infrastructure.FirstTimeLoginDetectionAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/home" />
<beans:property name="alwaysUseDefaultTargetUrl" value="true" />
<beans:property name="firstTimeLoginUrl" value="/firsttimelogin" />
</beans:bean>
<beans:bean id="customAuthenticationFalureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login" />
</beans:bean>
<beans:bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy" />
<beans:bean id="customAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler" ref="roleBasedAuthenticationSuccessHandler" />
<beans:property name="authenticationFailureHandler" ref="customAuthenticationFalureHandler" />
<beans:property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy" />
</beans:bean>
<beans:bean id="mySecurityContextRepository" class="org.mifosng.oauth.InMemoryOAuthTokenAwareSecurityContextRepository">
<beans:constructor-arg ref="tokenServices"/>
</beans:bean>
<!--
<beans:bean id="mySecurityContextPersistenceFilter" class="org.mifosng.oauth.OAuthTokenAwareSecurityContextPersistenceFilter">
<beans:constructor-arg ref="mySecurityContextRepository"/>
</beans:bean>
-->
<global-method-security pre-post-annotations="enabled" />
<http pattern="/" security="none" />
<http pattern="/resources/**" security="none" />
<http pattern="/api/open/**" security="none" />
<beans:bean id="loginForm" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login" />
</beans:bean>
<!-- SecurityContext no longer stored in session -->
<!--
on successful authentication, need to store token with association against authentication object
-->
<beans:bean id="requestCacheFilter" class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter" />
<!-- security-context-repository-ref="mySecurityContextRepository" -->
<http auto-config="false" create-session="always" use-expressions="true" pattern="/**"
entry-point-ref="loginForm" access-denied-page="/login"
>
<intercept-url pattern="/login" access="isAnonymous()" />
<intercept-url pattern="/logout" access="isAnonymous()" />
<intercept-url pattern="/pentahoreport*" access="isAnonymous()" />
<intercept-url pattern="/oauth/request_token" access="isAnonymous()" />
<intercept-url pattern="/oauth/confirm_access" access="isFullyAuthenticated()" />
<intercept-url pattern="/oauth/authorize" access="isFullyAuthenticated()" />
<intercept-url pattern="/oauth/access_token" access="isFullyAuthenticated()" />
<intercept-url pattern="/api/protected/**" access="isFullyAuthenticated()" />
<intercept-url pattern="/**" access="isFullyAuthenticated()" />
<!--
<custom-filter ref="customAuthenticationFilter" position="FORM_LOGIN_FILTER" />
<custom-filter ref="requestCacheFilter" after="FORM_LOGIN_FILTER"/>
-->
<logout logout-success-url="/logout" />
</http>
<beans:bean id="oauthProviderTokenServicesDelegate" class="org.mifosng.oauth.RemovableInMemoryProviderTokenServices" />
<beans:bean id="tokenServices" class="org.mifosng.oauth.CustomTokenServices">
<beans:constructor-arg ref="oauthProviderTokenServicesDelegate" />
</beans:bean>
<beans:bean id="consumerDetails" class="org.mifosng.oauth.MifosNgConsumerDetailsService" />
<oauth:provider
consumer-details-service-ref="consumerDetails"
token-services-ref="tokenServices"
request-token-url="/oauth/request_token"
authenticate-token-url="/oauth/authorize"
access-token-url="/oauth/access_token"
authentication-failed-url="/oauth/confirm_access"
access-granted-url="/request_token_authorized"
require10a="false"/>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
</beans:beans>
<!--
<security:global-method-security pre-post-annotations="enabled" />
<security:http pattern="/resources/**" security="none"/>
<security:http pattern="/api/open/**" security="none"/>
<security:http auto-config='true' access-denied-page="/login">
<security:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/logout" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/oauth/**" access="ROLE_USER" />
<security:intercept-url pattern="/api/protected/**" access="ROLE_USER" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login authentication-failure-url="/login" default-target-url="/index" login-page="/login" />
<security:logout logout-success-url="/logout" />
</security:http>
-->
<!--
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name="securityContextRepository" ref="securityContextRepository" />
</bean>
<bean id="securityContextRepository" class="org.springframework.security.web.context.NullSecurityContextRepository" />
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="/logout" />
<constructor-arg>
<list><bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" /></list>
</constructor-arg>
</bean>
<bean id="servletApiFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter" />
<bean id="anonymousAuthenticationFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter" >
<property name="key" value="SomeUniqueKeyForThisApplication" />
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
</bean>
<bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter" >
<constructor-arg ref="securityContextRepository" />
</bean>
<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="loginForm" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="securityMetadataSource">
<security:filter-security-metadata-source>
<security:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/logout" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/signup" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/pentahoreport*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/oauth/**" access="IS_AUTHENTICATED_FULLY" />
<security:intercept-url pattern="/api/protected/**" access="IS_AUTHENTICATED_FULLY" />
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
</security:filter-security-metadata-source>
</property>
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
</bean>
-->
<!-- org.springframework.security.oauth.provider.token.InMemorySelfCleaningProviderTokenServices -->
<!--
<bean id="oauthProviderTokenServicesDelegate" class="org.springframework.security.oauth.provider.token.InMemorySelfCleaningProviderTokenServices">
<property name="cleanupIntervalSeconds" value="30" />
</bean>
-->
<!--
<bean id="oauthRequestTokenFilter" class="org.springframework.security.oauth.provider.filter.UnauthenticatedRequestTokenProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/request_token" />
<property name="tokenServices" ref="oauthProviderTokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="oauthRandomValueVerifierServices" class="org.springframework.security.oauth.provider.verifier.RandomValueVerifierServices" />
<bean id="oauthAuthorizationSuccessHandler" class="org.springframework.security.oauth.provider.filter.UserAuthorizationSuccessfulAuthenticationHandler" />
<bean id="oauthUserAuthorizationFilter" class="org.springframework.security.oauth.provider.filter.UserAuthorizationProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/authorize" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="tokenServices" ref="oauthProviderTokenServices" />
<property name="verifierServices" ref="oauthRandomValueVerifierServices" />
<property name="authenticationSuccessHandler" ref="oauthAuthorizationSuccessHandler" />
</bean>
<bean id="oauthAccessTokenFilter" class="org.springframework.security.oauth.provider.filter.AccessTokenProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/access_token" />
<property name="tokenServices" ref="oauthProviderTokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="oauthProtectedResourceFilter" class="org.mifosng.oauth.CustomProtectedResourceProcessingFilter">
<property name="tokenServices" ref="oauthProviderTokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<filter-chain pattern="/resources/**" filters="none" />
<filter-chain pattern="/api/open/**" filters="none" />
<filter-chain pattern="/**" filters="securityContextPersistenceFilter, logoutFilter, customAuthenticationFilter,
requestCacheFilter, servletApiFilter, anonymousAuthenticationFilter, sessionManagementFilter, exceptionTranslationFilter,
oauthRequestTokenFilter, oauthUserAuthorizationFilter, oauthAccessTokenFilter, oauthProtectedResourceFilter,
filterSecurityInterceptor" />
</list>
</constructor-arg>
</bean>
-->