I have a Spring Security OAuth2 based RESTful application. I have been trying to change the default Spring Security messaging formats from XML to JSON and have been partially successful in doing so.
For eg - I figured out how to change the response format when the request does not contain Bearer token (the following line does it)
<bean id="oauthAuthenticationEntryPoint" class ="c.s.m.security.CustomAuthenticationEntryPoint" />
But I am not able to figure out how to catch/change the format of the below two items.
When an invalid token is being passed in the secured URL, Spring Security currently throws back. Where do I change this format?
{"error": "invalid_token","error_description": "Invalid access token: 144285e3-9563-420e-8ce"}
How do I change the BadCredentialsException JSON format? Currently, it returns a JSON similar to above?
Below is my applicationContext.xml
<sec:http pattern="/oauth/token" create-session="stateless"
use-expressions="true" authentication-manager-ref="authenticationManager">
<sec:csrf disabled="true" />
<sec:anonymous enabled="false" />
<sec:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<sec:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<sec:authentication-manager alias="authenticationManager"
erase-credentials="false">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- Entry point - Entry point Filter for token server -->
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="Oauth 2 security" />
<property name="typeName" value="Basic" />
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<!-- Oauth handler Access Denied Handler -->
<bean id="oauthAccessDeniedHandler" class="c.s.m.security.CustomAccessDeniedHandler" />
<!-- class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" /> -->
<!-- Server resource -->
<sec:http pattern="/api/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint" use-expressions="true" >
<sec:csrf disabled="true" />
<sec:anonymous enabled="false" />
<sec:intercept-url pattern="/api/**" access="hasRole('ROLE_ADMIN')" />
<sec:custom-filter ref="resourceServerFilter"
before="PRE_AUTH_FILTER" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<!-- Entry point resource -->
<bean id="oauthAuthenticationEntryPoint" class ="c.s.m.security.CustomAuthenticationEntryPoint" />
<oauth:resource-server id="resourceServerFilter" resource-id="springsec" token-services-ref="tokenServices" />
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices" >
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="300000" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<constructor-arg ref="dataSource" />
</bean>
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password authentication-manager-ref="userAuthenticationManager" />
</oauth:authorization-server>
<sec:authentication-manager id="userAuthenticationManager">
<sec:authentication-provider ref="customUserDetailsService" />
</sec:authentication-manager>
Send Accept: application/json in the request header will solve the problem.
Related
Can't seem to get spring oauth2 server configuration to successfully authenticate with a token.
I feel like I'm missing something very minute, but I'll take any pointers.
I'm attempting a password grant. I keep running into a 404 on /oauth/token. See my config and curl below (userAuthenticationProvider is injected by #Configuration on a custom provider):
CONFIGURATION:
<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" xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.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"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password authentication-manager-ref="clientAuthenticationManager" />
</oauth:authorization-server>
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="my-trusted-client"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT, ROLE_USER" scope="read,write,trust"
access-token-validity="60" />
<oauth:client client-id="my-trusted-client-with-secret"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="somesecret" authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT, ROLE_USER"
scope="read,write,trust" />
<oauth:client client-id="my-client-with-secret"
authorized-grant-types="client_credentials" authorities="ROLE_CLIENT, ROLE_USER"
scope="read" secret="secret" />
<oauth:client client-id="my-less-trusted-client"
authorized-grant-types="authorization_code,implicit" authorities="ROLE_CLIENT, ROLE_USER" />
<oauth:client client-id="my-less-trusted-autoapprove-client"
authorized-grant-types="implicit" authorities="ROLE_CLIENT, ROLE_USER" />
<oauth:client client-id="my-client-with-registered-redirect"
authorized-grant-types="authorization_code,client_credentials"
authorities="ROLE_CLIENT, ROLE_USER" redirect-uri="http://anywhere?key=value"
scope="read,trust" />
<oauth:client client-id="my-untrusted-client-with-registered-redirect"
authorized-grant-types="authorization_code" authorities="ROLE_CLIENT, ROLE_USER"
redirect-uri="http://anywhere" scope="read" />
<oauth:client client-id="tonr" resource-ids="sparklr"
authorized-grant-types="authorization_code,implicit" authorities="ROLE_CLIENT"
scope="read,write" secret="secret" />
</oauth:client-details-service>
<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" />
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="oAuth2RequestFactory"
class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<constructor-arg ref="clientDetails" />
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
<property name="tokenStore" ref="tokenStore" />
<property name="requestFactory" ref="oAuth2RequestFactory" />
</bean>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<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>
<http pattern="/oauth/check_token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager
xmlns="http://www.springframework.org/schema/security" alias="userAuthenticationManager">
<authentication-provider ref="userAuthenticationProvider">
<!-- <user-service> <user name="admin" password="adminpassword" authorities="ROLE_USER"
disabled="true" locked="true" /> <user name="user" password="userpassword"
authorities="ROLE_USER" /> </user-service> -->
</authentication-provider>
</authentication-manager>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<!-- <property name="realmName" value="test" /> -->
</bean>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</bean>
<!-- ACCESS DECISION AND ROLE VOTERS -->
<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" />
</list>
</constructor-arg>
</bean>
<sec:global-method-security
jsr250-annotations="enabled" access-decision-manager-ref="accessDecisionManager" />
CURL:
curl my-trusted-client-with-secret:somesecret#localhost:8080/oauth/token -d grant_type=password -d username=admin -d password=adminpassword
I'll take any pointers on on anything wrong.
I kept getting a 404 on /oauth/token even after spring security filter chain had authenticated my client because deployment descriptor ie web.xml was missing a Spring Dispatcher servlet configuration. Added the following and all was good:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/oauth/token</url-pattern>
</servlet-mapping>
With the below configuration during the first request, its redirecting to CAS server. But after login, its not redirecting back to the application. This is what is happening:
Open https://localhost:8443/test
Redirecting to https://localhost:9443/cas/login?service=https%3A%2F%2Flocalhost%3A8443%2Ftest%2F
After entering correct credentials, its not redirecting back to the application. URL on browser is the same CAS login URL and the page is broken because of ERR_TOO_MANY_REDIRECTS.
<security:http entry-point-ref="casEntryPoint">
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<security:custom-filter position="CAS_FILTER"
ref="casFilter" />
</security:http>
<bean id="casEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://localhost:9443/cas/login/" />
<property name="serviceProperties" ref="serviceProperties" />
</bean>
<bean id="casFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="casAuthenticationProvider" />
</security:authentication-manager>
<bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="authenticationUserDetailsService">
<bean
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<constructor-arg ref="userService" />
</bean>
</property>
<property name="serviceProperties" ref="serviceProperties" />
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://localhost:9443/cas/" />
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only" />
</bean>
<security:user-service id="userService">
<security:user name="admin" password="admin" authorities="ROLE_USER" />
</security:user-service>
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service" value="https://localhost:8443/test/" />
<property name="sendRenew" value="false" />
</bean>
This is resolved when I changed pattern of below configuration from /** to /newviews/** which is specific to my UI files.
<security:intercept-url pattern="/newviews/**" access="hasRole('ROLE_USER')" />
I have a web application which implements oauth2 and spring security. Also I have a mobile version of my web application which will access some protected resources of my web application. When I access my token url, it gives the access token ,refresh token, token_type, expires_in. I have a method which I want the android to have access to.
So this is the url to get an access token:
http://localhost:8080/LEAVE/oauth/token?scope=read,write,trust&grant_type=password&client_id=testclient&client_secret=testsecret&username=john&password=smith
And it gives me this:
{
"access_token": "23ac9377-6de7-47b7-aab9-8aebc9c499d4",
"token_type": "bearer",
"refresh_token": "e8e0238c-a98e-4be3-93a9-fbe24bcf6e1d",
"expires_in": 119,
"scope": "read,write,trust"
}
And now to access the protected resource:
http://localhost:8080/LEAVE/api/users?access_token=23ac9377-6de7-47b7-aab9-8aebc9c499d4
When I call this url , it gives me the following error:
{
"error": "invalid_token",
"error_description": "Invalid access token: 23ac9377-6de7-47b7-aab9-8 aebc9c499d4"
}
The class that is protected:
#Scope("session")
#RequestMapping("/api/users")
#Component("ParParkingRequestComponent")
public class LeaveComponentImpl implements LeaveComponent {
#RequestMapping(value = "/", method = RequestMethod.GET)
#ResponseBody
public String test(){
return "Yes It's working";
}
Here is my spring-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- This is default url to get a token from OAuth -->
<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"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/api/**" 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="/api/**" access="ROLE_APP" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</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>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="120" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="restapp"
authorized-grant-types="authorization_code,client_credentials"
authorities="ROLE_APP" scope="read,write,trust" secret="secret" />
<oauth:client client-id="restapp"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="restapp" authorities="ROLE_APP" />
</oauth:client-details-service>
<security:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<security:expression-handler ref="oauthExpressionHandler" />
</security:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
<!-- Spring security -->
<!-- <security:global-method-security
secured-annotations="enabled" />
-->
<security:http auto-config="false" authentication-manager-ref="authenticationManager" use-expressions="true" >
<!-- Override default login and logout pages -->
<security:form-login authentication-failure-handler-ref="failureClass" authentication-success-handler-ref="successClass"
login-page="/login.xhtml" default-target-url="dashboard.xhtml" />
<security:logout invalidate-session="true" logout-url="/j_spring_security_logout" success-handler-ref="LogoutAction" />
<security:session-management>
<security:concurrency-control max-sessions="10" error-if-maximum-exceeded="true" />
</security:session-management>
<security:intercept-url pattern="/jsf/**" access="isAuthenticated()" />
<security:intercept-url pattern="/run**" access="isAuthenticated()" />
<security:intercept-url pattern="/login.xhtml" access="permitAll" />
</security:http>
<bean id="successClass" class="com.car.SuccessAction"/>
<bean id="failureClass" class="com.car.FailureAction" >
<property name="defaultFailureUrl" value="/?login_error=true"/>
</bean>
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService" >
<security:password-encoder ref="passwordEncoder" hash="sha"/>
</security:authentication-provider>
</security:authentication-manager>
I have a Spring 4.1 web app, I use spring-security and spring session, spring session I want to use with websockets to keep the session without timeout as long as the websocket is working.
It all works fine but what I find is that I obviously have two sessions running, one for spring security and one for spring session.
This is my session.xml:
<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="localhost"/>
<property name="port" value="6379" />
</bean>
<bean class="org.springframework.session.data.redis.RedisOperationsSessionRepository" name="sessionRepository" >
<constructor-arg name="redisConnectionFactory" ref="jedisConnFactory" />
<!--<property name="defaultMaxInactiveInterval" value="60" />-->
</bean>
<bean class="org.springframework.session.web.http.HeaderHttpSessionStrategy" name="sessionStrategy" />
<bean name="springSessionRepositoryFilter" class="org.springframework.session.web.http.SessionRepositoryFilter">
<constructor-arg name="sessionRepository" ref="sessionRepository" />
</bean>
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" >
<property name="httpSessionStrategy" ref="sessionStrategy"/>
</bean>
And here is my security.xml:
<!-- Security -->
<bean id="userDetailsService" class="com.fg.ts.base.security.userdetails.CustomUserDetailsService" />
<bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder">
<constructor-arg value="${encoder.password}" />
</bean>
<sec:authentication-manager id="authenticationManager">
<sec:authentication-provider user-service-ref="userDetailsService">
<sec:password-encoder ref="passwordEncoder" />
</sec:authentication-provider>
</sec:authentication-manager>
<sec:global-method-security pre-post-annotations="enabled" secured-annotations="disabled"
jsr250-annotations="enabled" authentication-manager-ref="authenticationManager" />
<!-- Exclude the resources+error+auth pages from security filter -->
<sec:http pattern="/javax.faces.resource/**" security="none" />
<sec:http pattern="/images/**" security="none" />
<sec:http pattern="/css/**" security="none" />
<sec:http pattern="/ico/**" security="none" />
<sec:http pattern="/lib/**" security="none" />
<sec:http pattern="/js/**" security="none" />
<sec:http pattern="/auth/**" security="none" />
<sec:http pattern="/error/**" security="none" />
<sec:http pattern="/api/concordancer/search/**" security="none" />
<sec:http pattern="/concordancer/search" security="none"/>
<sec:http pattern="/assets/cdSearch.xhtml" security="none"/>
<sec:http pattern="/api/tmGroup/**" security="none"/>
<sec:http pattern="/api/reports/download/**" security="none"/>
<sec:http pattern="/api/socket/tasks/info/**" security="none"/>
<!-- Security Configuration for Faces Pages -->
<!-- Start Customization for Faces -->
<!-- ***************************** -->
<!-- Failure Login Handler -->
<bean id="authenticationFailureHandler" class="com.fg.ts.web.util.security.LoginFailureHandler">
<property name="defaultFailureUrl" value="/auth/login" />
</bean>
<!-- Faces Redirect -->
<bean id="facesRedirectStrategy" class="com.fg.ts.web.util.security.FacesRedirectStrategy">
<property name="invalidSessionUrl" value="/auth/login/sessionExpired" />
</bean>
<!-- Shared Objects -->
<bean id="securityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<!-- Session Authentication Strategy -->
<bean id="sessionFixationAuthenticationStrategy" class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />
<bean id="registerSessionStrategy" class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
</bean>
<bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<constructor-arg name="delegateStrategies">
<list>
<!-- <ref bean="concurrentSessionStrategy" /> -->
<ref bean="sessionFixationAuthenticationStrategy" />
<ref bean="registerSessionStrategy" />
</list>
</constructor-arg>
</bean>
<!-- Remember-Me Service -->
<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<constructor-arg name="key" value="${encoder.password}" />
<constructor-arg name="userDetailsService" ref="userDetailsService" />
<property name="parameter" value="j_remember_me" />
<property name="cookieName" value="TMS_REME" />
</bean>
<!-- Filters -->
<bean id="usernamePasswordAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy" />
<property name="rememberMeServices" ref="rememberMeServices" />
<property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
</bean>
<bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
<constructor-arg name="securityContextRepository" ref="securityContextRepository" />
<constructor-arg name="sessionStrategy" ref="sessionAuthenticationStrategy" />
<property name="invalidSessionStrategy" ref="facesRedirectStrategy" />
<property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
</bean>
<bean id="concurrentSessionFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<constructor-arg name="expiredUrl" value="/auth/login/expiredDueToConcurrentAccess" />
<property name="redirectStrategy" ref="facesRedirectStrategy" />
</bean>
<bean id="authEntryPoint" class="com.fg.ts.web.util.security.FacesLoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/auth/login"/>
</bean>
<!-- End Customization for Faces -->
<!-- ***************************** -->
<sec:http use-expressions="true" disable-url-rewriting="true" authentication-manager-ref="authenticationManager"
entry-point-ref="authEntryPoint"> <!--security-context-repository-ref="securityContextRepository"-->
<sec:http-basic />
<sec:custom-filter ref="usernamePasswordAuthenticationFilter" before="FORM_LOGIN_FILTER" />
<sec:custom-filter ref="sessionManagementFilter" position="SESSION_MANAGEMENT_FILTER" />
<sec:anonymous />
<sec:remember-me key="${encoder.password}" services-ref="rememberMeServices" />
<sec:form-login login-page="/auth/login" authentication-failure-handler-ref="authenticationFailureHandler" />
<sec:logout logout-url="/logout" invalidate-session="true" delete-cookies="TMS_SES,TMS_REME"
logout-success-url="/auth/login" />
<sec:session-management session-fixation-protection="none" />
<!-- General Access Control -->
<sec:intercept-url pattern="/projects/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/assets/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/setup/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/tm/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/termBase/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/quality/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/editor/**" access="isAuthenticated()" />
<sec:intercept-url pattern="/api/**" access="isAuthenticated()" />
<sec:intercept-url pattern="/**" access="isAuthenticated()" />
</sec:http>
How can I make spring security use the session created by spring-session ?
I found the issue, the reason was that in the FilterChain, springSecurityFilterChain Filter always loaded first before the springSessionRepositoryFilter, and so the Spring Session was not yet created, so the security filter created it's own.
this was happening because my springSessionRepositoryFilter was configured specifically for each servlet like this:
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<servlet-name>mvc-dispatcher</servlet-name>
</filter-mapping>
but when I removed it and made it a global filter it then worked, much like this:
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I'm trying to redirect user to previous page after success login, but every time i got redirect to "/". There is my config:
<bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<constructor-arg name="rememberMeServices" ref="rememberMeServices"/>
<constructor-arg name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices" >
<constructor-arg name="tokenRepository" ref="persistentTokenRepository" />
<constructor-arg name="userDetailsService" ref="customUserDetailService"/>
<constructor-arg name="key" value="token"/>
<property name="cookieName" value="token" />
<property name="tokenValiditySeconds" value="864000" />
</bean>
<bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<constructor-arg name="key" value="token"/>
</bean>
<bean id="persistentTokenRepository" class="com.youtasked.spring.auth.MongoPersistentTokenRepositoryImpl" />
<sec:http auto-config="true" use-expressions="true">
<sec:session-management />
<sec:form-login login-page="/login" default-target-url="/" always-use-default-target="true" authentication-failure-url="/login?error=true"
login-processing-url="/j_spring_security_check" authentication-success-handler-ref="successLoginHandler"/>
<sec:logout logout-success-url="/logout" delete-cookies="true" invalidate-session="true" />
<sec:remember-me services-ref="rememberMeServices" use-secure-cookie="true" />
</sec:http>
<bean id="successLoginHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="useReferer" value="true" />
</bean>
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />
<bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<property name="userPropertyToUse" value="email" />
</bean>
<bean id="customUserDetailService" class="com.youtasked.core.user.CustomUserDetailService" />
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider user-service-ref="customUserDetailService">
<sec:password-encoder ref="passwordEncoder">
<sec:salt-source ref="saltSource"></sec:salt-source>
</sec:password-encoder>
</sec:authentication-provider>
<sec:authentication-provider ref="rememberMeAuthenticationProvider" />
</sec:authentication-manager>
In SavedRequestAwareAuthenticationSuccessHandler every time i'm getting null from requestCache, but i think it should be a previous request. Also i was reading about ExceptionTranslationFilter and some magic way to save requests using it, but i couldn't find any examples