Configure datasource for integrating Spring Security in existing Spring project - java

I am implementing spring security in an existing spring mvc project. I had used xml to configure the spring security. I have used this tutorial for implementing spring security
http://www.mkyong.com/spring-security/spring-security-form-login-using-database/
In my project I have a db-source file(MySQL_Datasource.xml) in resources folder just under main (outside of webapp). And the way spring security is implemented in tutorial, the datasource needs to be under webapp folder. I am facing this problem of integration.
Below is the snap of my project structure and on the right side config. code of web.xml, I have commented on the line in image where i have to define my dataSource location.
This is code of spring security where dataSource will be used
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-3.2.xsd">
<!-- enable use-expressions -->
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
default-target-url="/welcome"
authentication-failure-url="/login?error"
username-parameter="usr"
password-parameter="pwd" />
<logout logout-success-url="/login?logout" />
<!-- enable csrf protection -->
<csrf/>
</http>
<!-- Select users and user_roles from database -->
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query=
"select username,password, enabled from users where username=?"
authorities-by-username-query=
"select username, role from user_roles where username =? " />
</authentication-provider>
</authentication-manager>
</beans:beans>
I am doing this first time. I need help so that I can get this done.
UPDATE:
MYSQL_DataSource.xml code:
<bean id="dataSource" class= "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>db.properties</value>
</property>
</bean>
and below is the db.properties values:
jdbc.url = jdbc:mysql://localhost/bhaiyag_prod_grocery
jdbc.username = newuser
jdbc.password = kmsg

If your project is correctly configured, src/main/resources folder will be packaged during project build under WEB-INF/classes.
So, if maven configuration or deployment-assembly section in project/properties is Ok, the path that you should use in your web.xml is like this:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/groceryapp-servlet.xml
/WEB-INF/spring-security.xml
/WEB-INF/classes/MySQL_DataSource.xml
</param-value>
</context-param>
It should work this way.
Once it works, have a look at this question and answers spring-scheduler-is-executing-twice and this one too web-application-context-root-application-context-and-transaction-manager-setup. In many of the Mkyong's tutorials the application context is loading twice, and I'm pretty sure it would happen the same with your project once it starts working.
As your groceryapp-servlet.xml is already loaded by Spring MVC's dispatcher servlet, you could try just removing it from contextConfigLocation setting, just this way:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
/WEB-INF/classes/MySQL_DataSource.xml
</param-value>
</context-param>
Properties loading problem:
To load correctly the db.properties, try this config in DB config xml:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:/db.properties</value>
</property>
</bean>

You can also specify context location relatively to current classpath. Make sure the resources folder is on your classpath and if it is. Then you can load the configuration file in your resources folder like,
<context-param>
<param-value>classpath:MySQL_DataSource.xml</param-value>
</context-param>

Related

spring-security.xml hardcoded password [duplicate]

I am using Spring Security in one of my project. The web-app requires the user to login. Hence I have added few usernames and passwords in the spring-security-context.xml file as follows:
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user_1" password="password_1" authorities="ROLE_USER" />
<user name="user_2" password="password_2" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
My question is, how to move these username-password pairs to a different file (like some properties file) instead of keeping them in spring-security-context.xml? And how to read that file properties file?
You can store the usernames and passwords in a separate .properties file.
<user-service id="userDetailsService" properties="users.properties"/>
users.properties should have the following format:
jimi=jimispassword,ROLE_USER,ROLE_ADMIN,enabled
bob=bobspassword,ROLE_USER,enabled
If you want to store it in a database, I would recommend you to read this article: http://www.mkyong.com/spring-security/spring-security-form-login-using-database/
Reference: Spring Security In-Memory Authentication
You can use the PropertyPlaceholderConfigurer - put them in properties file and then reference them using EL:
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-placeholderconfigurer
You can find a way to move them to a database or LDAP. Spring Security surely supports both.
I have tried the suggested ways lastly I did the following seemed to work nicely
Added these changes in your web xml
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet-mapping>
<servlet-name>service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Add these changes in your spring-security xml
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider>
<security:user-service>
<security:user name="${resource.service.authentication.name}"
authorities="${resource.service.authentication.authorities}"
password="${resource.service.authentication.password}"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
Add these changes into your application context xml or if you have property-loader xml even
better
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="placeholderPrefix" value="${" />
<property name="placeholderSuffix" value="}" />
<property name="locations">
<list>
<value>classpath:resourceservice.properties</value>
</list>
</property>
</bean>
Then Add these changes in your property file resourceservice.properties
memberservice.authentication.name=usename
memberservice.authentication.authorities=AUTHORISED
memberservice.authentication.password=password
Add these changes in you resource that uses Jersey
#PUT
#Path("{accountId}")
#Consumes("application/xml")
#PreAuthorize("hasRole('AUTHORISED')")
public Response methodName
This works for me for Spring security authentication and authorization using Properties file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<mvc:annotation-driven />
<bean id="webPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:abc.properties</value>
</list>
</property>
</bean>
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/stat/login" access="permitAll"/>
<security:intercept-url pattern="/stat/summary" access="hasRole('ROLE_ADMIN')" />
<security:form-login login-page="/stat/login"
default-target-url="/stat/summary" authentication-failure-url="/stat/loginError" />
</security:http>
<!-- Username and password used from xml -->
<!-- <security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="xyz" password="xyz" authorities="ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager> -->
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="${stat.user}" password="${stat.pwd}" authorities="ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
The abc.properties file:
stat.user=xyz
stat.pwd=xyz
The web.xml entry for spring-security implementation:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
You can simply add Bean inside your Spring Security Configuration :
#Bean
public UserDetailsService userDetailsService() {
Properties users = PropertiesLoaderUtils.loadAllProperties("users.properties");
return new InMemoryUserDetailsManager(users);
}
and users.properties looks like :
admin={noop}password,ROLE_USER,ROLE_ADMIN,enabled
bob={noop}password,ROLE_USER,enabled
123={noop}123,ROLE_USER,enabled

Spring Security 3.1.1 + Jboss 7 Error

I'm having some throblems when I try to deploy an application which use spring securety on Jboss, the error is:
Caused by: java.lang.IllegalArgumentException: A universal match pattern ('/**') is defined before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration
This is my applicationContext-securety.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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 security configurations -->
<!--<global-method-security pre-post-annotations="enabled"/>-->
<http pattern="/ext/**" security="none" />
<http pattern="/resources/**" security="none" />
<http pattern="/**" security="none" />
<http auto-config="true" use-expressions="true" disable-url-rewriting="true" entry-point-ref="tendwebEntryPoint">
<!-- Configure these elements to secure URIs in your application -->
<intercept-url pattern="/index.jsp" access="isAuthenticated()" />
<!-- Filter -->
<custom-filter ref="mockimiAuthenticationFilter" after="FORM_LOGIN_FILTER"/>
</http>
<authentication-manager alias="authenticationManager" />
<beans:bean id="imiAuthenticationFilter" class="com.tend.imi.web.security.imiAuthenticationFilter">
<beans:property name="tendwebFilter" ref="tendWebFilter" />
<beans:property name="imiUserDetailsService" ref="imiUserDetailsService"/>
</beans:bean>
<!-- Filtro de la tendweb -->
<beans:bean id="tendWebFilter" class="Gci.utils.http.LoginFilter" />
<beans:bean id="tendwebEntryPoint" class="com.tend.imi.web.security.imiwebEntryPoint" />
<beans:bean id="imiUserDetailsService" class="com.tend.imi.web.security.imiUserDetailsService" />
And I'm using this in the web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
Can anybody help me? I searched a lot but it didn't work.
Possibly a double for this question.
The problem is that you say /** is open to any user, but then you try to use auto-config.
According to the error code, this causes conflict because spring doesn't know whether /index.jsp is supposed to be open for all users or only authenticated ones.
Thanks Sir Celius for your answer.
Finally I resolved my problem. The error was in the declaration of contextConfigLocation in the web.xml, I had this:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
I don't know why, but the use of the special character "*" doesn't like to Jboss, I just change this and everything works.
I deployed this application in tomcat and weblogic and this never happend ... I think its an error that Jboss has to fix.

restrict user to authenticate before viewing pages using spring security java

I am new to Spring framework and Spring security. I am developing an application using google app engine. I am trying to authenticate the user but cant able to achieve it. My problems here are
I need to restrict the all the user to type the URL in the browser and to see the pages. If they want to access such pages I need to navigate them to the warning page.
An user can access the application only if he is authenticated with the application. If not authenticated the login page should be navigated.
I need to write a custom login authenticated page where in the page i should authenticate them if given credentials are perfect then we can navigate them to the main page.
In the custom login authentication page we should write the database logic to get the credentials from the db and authenticate. And if the user is not registered with the application then we should navigate them to the registration page with a default message.
Please any one can give me the default application with this requirements.
Thanks and Regards,
Sree
I am using spring 3.x to complete the configuration
in web.xml, add these lines
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
comes to security xml page add these. And i am using DAOAuthenticationProvider. And password encoding i am using BCryptPasswordEncoder.
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-3.1.xsd">
<http use-expressions="true">
<form-login login-page="/login" always-use-default-target="true" default-target-url="/sessionInit" authentication-failure-url="/login"/>
<logout logout-url="/logout" logout-success-url="/logout"/>
</http>
<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" ></beans:property>
</beans:bean>
<beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="daoAuthenticationProvider"/>
</beans:list>
</beans:property>
</beans:bean>
<authentication-manager>
<authentication-provider ref="authProvider"></authentication-provider>
</authentication-manager>
<beans:bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="encoder" />
</beans:bean>
<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
</beans:beans>
before all these configuration you need add this security.xml file in the web.xml.

Spring-security context setup for 2-legged (client credentials) OAuth2 server

What's the minimal setup for spring-security OAuth2 if I want to secure a REST server for one client? I don't want to use any unnecessary setup or implement any unnecessary beans. Maybe there's an "easy" tutorial / example out there already for spring-security + OAuth2? (Though I'm trying to avoid being too hopeful about that)
My current working setup (working with the copy+past+wtf from the sparklr context) feels like too much:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2-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/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:client-credentials />
</oauth:authorization-server>
<sec:authentication-manager alias="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<oauth:resource-server id="resourceServerFilter"
resource-id="rest_server" token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="the_client" authorized-grant-types="client_credentials"
authorities="ROLE_RESTREAD" secret="1234567890" />
</oauth:client-details-service>
<http pattern="/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/rest/**" access="ROLE_RESTREAD" method="GET" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="false" />
<property name="clientDetailsService" ref="clientDetails" />
<property name="accessTokenValiditySeconds" value="400000" />
<property name="refreshTokenValiditySeconds" value="0" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="theRealm" />
</bean>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="theRealm/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
</beans>
I already have implemented the authenticationManager (UserDetailsService) as a part of implementing basic spring-security so that accounts and roles are persisted against our database.
The beans I don't really get are:
userApprovalHandler: Why would I need any user approval in a client_credentials flow / grant? It seems, sparklr overrides the default TokenServicesUserApprovalHandler to auto-approve one client. Do I need to do that as well for the communication between my trusted client(s) and the server?
oauthAuthenticationEntryPoint: all sparklr does about this is:
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="sparklr2" />
</bean>
What's that supposed to do?
clientCredentialsTokenEndpointFilter
It says, I should include this only if I want to authenticate via request parameters.. So what I have in mind is exactly that: Send a GET(?) request to my server with the secret and get a token and with that token access the resources? So I'm thinking, the request for the token should contain the secret as request parameter..?
resourceServerFilter
It seems to me that this indicates a separate resource server? How does that apply if my resources are on the same server as the authentication provider?
accessDecisionManager
I don't remember having to use this when setting up my custom spring-security implementation, why would I want to do so now?
Thanks for reading through! Hope someone can answer a few of my questions..
Update
I've updated the setup to the current working state. I can now request an access token with the client credentials:
$ curl -X -v -d 'client_id=the_client&client_secret=secret&grant_type=client_credentials' -X POST "http://localhost:9090/our-server/oauth/token"
and use that token to access protected resources:
$ curl -H "Authorization: Bearer fdashuds-5432fsd5-sdt5s5d-sd5" "http://localhost:9090/our-server/rest/social/content/posts"
It still feels like a lot of setup and my questions remain. Also I'm wondering if this is the right way to go for securing the communication between trusted client and REST server in general.
It also still feels like the initial request for the token is not secure except if done via https, but will that suffice?
Also what about the token itself, should I give it a long lifetime and persist it on the client? that would in any case mean catching a token expiration exception and then requesting a new one. Or should I do the handshake for every request? What about refreshing the token? I think I read somewhere that refresh token is not secure for the client credentials grant type..? Is it necessary to send the token as HTTP header or can I change that? I don't want to use the spring-security client stack for our client as it has a rather legacy setup (jboss 5) and all we did so far was integrate REST communication capabilities with request parameters..
It would also help to know more about all the spring-security setup but the documentation is quite thin..
EDIT
Updated the spring security configuration to our current state. Also, here's our web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>the-display-name</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>base.package.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/servlet-context.xml
</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Note: The spring-security-context.xml from above will get initialized by the servlet-context. The spring-context.xml itself only initializes the beans.
(Also: Our Server also has a few views so all rest resources run under /rest hence the url-pattern. But: It is always necessary to have a separate servlet and spring context.)
userApprovalHandler: if you only have one client in your system, I agree the users should not have to approve it accessing their data.
oauthAuthenticationEntryPoint: Normally, if authentication fails, the response type is JSON. Documentation says "If authentication fails and the caller has asked for a specific content type response, this entry point can send one, along with a standard 401 status."
clientCredentialsTokenEndpointFilter: Issuing an access token is a two-step process. First, you send the user to the resource server to authenticate. This redirect is authenticated by the client, ideally with the HTTP Headers (key + secret). In return, the client gets a code, which can be exchanged for a token.
You do not directly trade the key+secret for a token, as it contains no approval from the user.
resourceServerFilter: I think the purpose of this is indicating what clients have access to what resources, if you have many different resources.
accessDecisionManager: For OAuth2 you need a ScopeVoter, so the default Manager is not good enough.
Generally:
If you will only have one client accessing the resources on behalf of the users, then maybe consider using Digest instead of OAuth2?
And if you only want to authenticate the client (not the user), then OAuth2 is overkill. Client authentication in OAuth2 is really same as Basic Authentication over https.
A good example of oauth2 for REST clients and users with spring security ouath 2.0:
http://www.e-zest.net/blog/rest-authentication-using-oauth-2-0-resource-owner-password-flow-protocol/

How to access beans in across different xml files

I have three xml files in my spring hibernate app
Spring-Security.xml
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
</security:authentication-provider>
</security:authentication-manager>
<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
<!-- A custom service where Spring will retrieve users and their corresponding access levels -->
<bean id="customUserDetailsService" class="com.vaannila.service.CustomUserDetailsService" >
</bean>
hibernate-context.xml
enter code here
<!-- Declare a datasource that has pooling capabilities-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}"
p:user="${app.jdbc.username}"
p:password="${app.jdbc.password}"
p:acquireIncrement="5"
p:idleConnectionTestPeriod="60"
p:maxPoolSize="100"
p:maxStatements="50"
p:minPoolSize="10" />
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<bean id="registrationDAO" class="com.vaannila.dao.RegistrationDAOimpl" >
<constructor-arg ref="sessionFactory"/>
</bean>
Now in my spring security i want something like
<bean id="customUserDetailsService" class="com.vaannila.service.CustomUserDetailsService" >
<constructor-arg ref="registrationDAO"/>
</bean
but my registrationDAO is in hibernate-config and when i do that in spring Security it says no bean named registration DAO
Spring supports reading application context across external jars. Simply add "classpath:" prefix to the context file name. Spring will look for it in the whole project.
For instance, if you are creating web application, you might declare your business logic application context like this (web.xml)
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml <!-- tell Spring to look for context defined on the classpath -->
</param-value>
</context-param>
That way You'll be able to use as many context, as necessary.

Categories