ConcurrentSessionControlStrategy in spring security 3.2.4 - java

I had a working configuration with ConcurrentSessionControlStrategy and my own sessionRegistry implementation. I upgraded to spring security 3.2.4 and had to change ConcurrentSessionControlStrategy to ConcurrentSessionControlAuthenticationStrategy. and now it seems that the sessionRegistry isn't connected meaning ConcurrentSessionControlAuthenticationStrategy.onAuthenticaton doesn't enter the sessionRegistry.registerNewSession. What to de?
my configuration xml:
<security:http use-expressions="true" auto-config="false"
entry-point-ref="loginUrlAuthenticationEntryPoint">
<security:intercept-url pattern="/**"
access="isAuthenticated()" />
<security:custom-filter position="FORM_LOGIN_FILTER"
ref="twoFactorAuthenticationFilter" />
<security:logout logout-url="/player/logout"
logout-success-url="/demo/player/logoutSuccess" />
<security:session-management>
<security:concurrency-control
max-sessions="1" session-registry-ref="clusteredSessionRegistryImpl"
error-if-maximum-exceeded="false" />
</security:session-management>
</security:http>
<bean
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<constructor-arg ref="clusteredSessionRegistryImpl" />
<property name="maximumSessions" value="1" />
</bean>
<bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/demo/player/login?login_error=true" />
</bean>
<bean id="twoFactorAuthenticationFilter" class="com.XXX.filter.TwoFactorAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationFailureHandler" ref="failureHandler" />
<property name="authenticationSuccessHandler" ref="playerAuthenticationSuccessHandler" />
<property name="postOnly" value="true" />
</bean>
<bean id="failureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login?login_error=true" />
</bean>
<bean id="bCryptPasswordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="authenticationProvider">
</security:authentication-provider>
</security:authentication-manager>
</beans>

Seems I'm late with the answer, but any way..
The functionality of ConcurrentSessionControlStrategy is exactly split between three Strategies now - ConcurrentSessionControlAuthenticationStrategy, SessionFixationProtectionStrategy and RegisterSessionAuthenticationStrategy.
To have a right substitute, you should use CompositeSessionAuthenticationStrategy adding these three delegates in mentioned order.
So, afraid, ConcurrentSessionControlAuthenticationStrategy is wrongly mentioned in deprecation comment as a substitute of ConcurrentSessionControlStrategy. It at least requires availability of RegisterSessionAuthenticationStrategy to maintain SessionRegistry. Otherwise, SessionRegistry remains empty, and the "substitute" always reports "ok".
I guess, the approach is changed to make it more flexible having several handlers as delegates instead of one (using CompositeSessionAuthenticationStrategy, you can have any number of SessionAuthenticationStrategy's doing independent :) things).

Related

Spring Authorization not kicking off

I have the following spring security xml file, which has authentication and authorization configuration. The problem here is the authentication works fine but the authorization is not kicking off, its not even retrieving role. I have worked on similar kind of scenario earlier but had no problems. The only difference was I was using spring 3 that time now this is with spring 4. Any thing that I am missing here or something I am doing wrong.
<security:authentication-manager alias="preAuthManager">
<security:authentication-provider ref="preAuthProvider" />
</security:authentication-manager>
<bean id="preAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="frfPreAuthUserDetailsService" />
</bean>
<bean id="frfPreAuthProcessingFilter" class="*.*.*.ws.infra.FRFPreAuthenticatedProcessingFilter">
<property name="authenticationManager" ref="preAuthManager" />
<property name="stripDomain" value="true" />
<property name="toLowerCase" value="true" />
</bean>
<bean id="preAuthEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<bean id="frfPreAuthUserDetailsService" class="*.*.*.ws.infra.FRFPreAuthenticatedUserDeatilsService">
<!-- Configure the Role Service ... 1) InMemoryRoleRetriever 2) Arrow2RoleRetriver; This configuration is shown below...-->
<property name="roleService" ref="arrow2RoleServiceImpl" />
</bean>
<bean id="arrow2RoleServiceImpl" class="*.*.*.ws.arrowrest.ArrowRoleRetriever">
<constructor-arg index="0" value="${arrow.rest.endPoint}" />
<constructor-arg index="1" value="authorized-function-names" />
<constructor-arg>
<map>
<entry key="CallerName" value="${arrow.appName}"></entry>
<entry key="ApplicationName" value="${arrow.appName}"></entry>
</map>
</constructor-arg>
</bean>
<!-- <global-method-security pre-post-annotations="enabled"/> -->
<security:global-method-security secured-annotations="enabled"/>
<security:http pattern="/WEB-INF/jsp/access_denied.jsp" security="none"/>
<security:http pattern = "/app/*" create-session="never" use-expressions="false" auto-config="false" entry-point-ref="preAuthEntryPoint"
authentication-manager-ref="preAuthManager"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<security:custom-filter ref="frfPreAuthProcessingFilter" before="PRE_AUTH_FILTER" />
<security:intercept-url pattern="/app/3a4/rules" method="GET" access="ROLE_ADMIN"/>
</security:http>
<!-- Allows access if principal has the proper granted authority -->
<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.access.vote.RoleVoter" />
</list>
</constructor-arg>
<property name="allowIfAllAbstainDecisions" value="false" />
</bean>

CAS Spring client - redirection back to the applicatrion is failing because of ERR_TOO_MANY_REDIRECTS

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')" />

Spring Security OAuth2 Change JSON Error Response Format

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.

Autowiring not happening during certain request

I am a newbie to spring-security.I have a issue with #Autowired annotation.
Below is my spring-security.xml file:
<http pattern="/login" security="none" />
<http pattern="/signup" security="none" />
<http pattern="/views/**" security="none" />
<http pattern="/createUser" security="none" />
<http pattern="/practice" security="none" />
<http use-expressions="true" authentication-manager-ref="authenticationManager">
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login" default-target-url="/home"
authentication-failure-url="/login" username-parameter="username"
password-parameter="password" login-processing-url="/j_spring_security_check" />
<logout logout-success-url="/login" invalidate-session="true"
logout-url="/j_spring_security_logout" delete-cookies="JSESSIONID" />
<session-management invalid-session-url="/login">
<concurrency-control max-sessions="1"
expired-url="/login" />
</session-management>
</http>
<authentication-manager id="authenticationManager">
<authentication-provider user-service-ref="userDetailsService" />
</authentication-manager>
<beans:bean id="userDetailsService" class="com.practice.service.UserDetailsServiceImpl" />
<beans:bean name="
passwordEncoder "
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
This is my spring-servlet.xml configuration:
<context:annotation-config/>
<context:component-scan base-package="com.practice" />
<mvc:resources mapping="/views/**" location="/views/" />
<mvc:annotation-driven />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations"
value="classpath:com/practice/resources/database.properties"></property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:com/practice/resources/hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
I would request for signup page, and after filling the necessary details , it hits my controller , where i save the user in the database, then i authenticate the user, in the request against the one which i stored in the database. I followed this stackoverflow post for guidance.
The strange thing is the autowiring is not happening in the class, where i implement the UserDetailsService interface :
#Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
PasswordEncoder passwordEncoder;
#Autowired
UserService userService;
#Override
public UserDetails loadUserByUsername(String arg0)
throws UsernameNotFoundException {
System.out.println("ddfddd");
return null;
}}
Whereas autowiring is taking place in other service classes , where i autowired the same fields as mentioned above !!
The same thing happens when i do a login , and when i debugged , the fields are null ! and also in the classes where i wrote my CustomAuthenticationProvider !
Any suggestion ?? If there is any mistake in my configuration do correct me.
Update
I am getting the following error,
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.practice.service.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
when i remove #Service annotation and when i add context:annotation-config
If you have defined a UserService bean with an #Component annotation, which is picked up by the component scan in spring-servlet.xml, then the problem could be, that spring-servlet.xml is a child application context from spring-security.xml. In that case, beans from the security context aren't able to access any beans from the child context, only the other way round. So you have to make sure, that all required beans are accessible from the spring-security.xml context (e.g. by specifying all beans explicitly or by moving the annotation-config and component-scan elements in the spring-security.xml context).

Spring Security 3 redirect after login

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

Categories