spring security session times out - spring

I am using spring security 4.1, the issue that i face is when i try to login i am sent back to the session expired page several times. I have tried multiple things like adding my own HttpSessionListener also by adding
org.springframework.security.web.session.HttpSessionEventPublisher
but the session keeps expiring. I read in one of the questions the explanation for such behavior
"It's possible for Spring Security to invalidate session in some cases (for example, after logging in, the user gets a new HttpSession)."
I used Fiddler tool to see what is happening, i see user is authenticated but is redirected to session expired page instantly. I want to allow same user to login as many times as he wants. I also read in some places that it will help to move to spring 3.x but i assume it might be for cases when older version of spring was used.
please suggest. Thank You
<http auto-config="true" use-expressions="true"
authentication-manager-ref="authenticationManager">
<session-management
invalid-session-url="/login?eventType=sessionTimedOut"
session-fixation-protection="none"
/>
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/*" access="hasAnyAuthority('FF_USER','FF_ADMIN')" />
<form-login login-page="/login"
authentication-success-handler-ref="authenticationSuccessHandler"
authentication-failure-handler-ref="customAuthenticationFailureHandler"
login-processing-url="/j_spring_security_check"
username-parameter="j_username"
password-parameter="j_password"
/>
<logout invalidate-session="false" logout-success-url="/login?eventType=logout"
logout-url="/j_spring_security_logout" delete-cookies="JSESSIONID"/>
<csrf token-repository-ref="csrfTokenRepository" />
</http>
<beans:bean id="csrfTokenRepository"
class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">
<beans:property name="headerName" value="X-XSRF-TOKEN" />
</beans:bean>
<beans:bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/home"/>
<beans:property name="alwaysUseDefaultTargetUrl" value="true"/>
</beans:bean>
<beans:bean id="customAuthenticationFailureHandler" class="*.*.CustomAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login?eventType=error"></beans:property>
<beans:property name="baseFailureUrl" value="/login?eventType=error"></beans:property>
</beans:bean>
<beans:bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<beans:constructor-arg>
<beans:list>
<beans:ref bean="ldapAuthenticationProvider" />
</beans:list>
</beans:constructor-arg>
<beans:property name="eraseCredentialsAfterAuthentication"
value="true" />
</beans:bean>

<http>
<logout delete-cookies="JSESSIONID" />
</http>
Unfortunately this can't be guaranteed to work with every servlet container, so you will need to test it in your environment[8].
So you need to add a customer logout handler that implements LogoutHandler to LogoutFilter handlers.
<http auto-config="true" use-expressions="true" authentication-manager-ref="authenticationManager">
...
<custom-filter ref="logoutFilter" position="LOGOUT_FILTER" />
...
</http>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg name="logoutSuccessUrl" value="/login?eventType=logout" />
<!-- implement LogoutHandler, Websphere log out -->
<constructor-arg name="handlers" ref="{customer logout }" />
<property name="filterProcessesUrl" value="/j_spring_security_logout" />
</bean>

Related

Spring Security CAS and HttpBasic, CasAuthentcationProvider not invoked after ticket granted

I have a maven multi-modules application where the main module depends on others. This main module is secured with Spring Security CAS and submodules required a basic authentication. This is a example of the security configuration of a submodule:
<security:http name="boobkingapiHttp" create-session="stateless" pattern="/hub/book/**"
authentication-manager-ref="apiAuthenticationManager">
<security:intercept-url pattern="/hub/book" access="ROLE_ORDER_MANAGER" />
<security:http-basic />
</security:http>
And the security configuration for the main module:
<security:http entry-point-ref="casEntryPoint" pattern="/**" realm="ecab" use-expressions="false">
<security:intercept-url pattern="/flow/googlestatistics/**" access="ROLE_ADMIN" />
<security:intercept-url pattern="/**" access="ROLE_ADMIN" />
<security:custom-filter position="CAS_FILTER" ref="casFilter" />
<security:logout logout-success-url="/logout.xhtml"/>
<security:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
<security:custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
</security:http>
<beans:bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<beans:bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<beans:property name="loginUrl" value="http://localhost:8082/sso/login" />
<beans:property name="serviceProperties" ref="serviceProperties" />
</beans:bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider" />
</security:authentication-manager>
<beans:bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<beans:property name="authenticationUserDetailsService">
<beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:constructor-arg ref="hwsAuthenticationUserDetailsService" />
</beans:bean>
</beans:property>
<beans:property name="serviceProperties" ref="serviceProperties" />
<beans:property name="ticketValidator">
<beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<beans:constructor-arg index="0" value="http://localhost:8082/sso" />
</beans:bean>
</beans:property>
<beans:property name="key" value="an_id_for_this_auth_provider_only" />
</beans:bean>
<beans:bean id="serviceProperties"
class="org.springframework.security.cas.ServiceProperties">
<beans:property name="service" value="http://localhost:8080/cas-client/login/cas" />
<beans:property name="sendRenew" value="false" />
</beans:bean>
The problem is, when the CAS server grants the ticket and redirects to the service url: http://localhost:8080/cas-client/login/cas?ticket=ST-19-1clKw2tZ5MVp0OznfAun the casAuthenticationProvider is not invoked. The one invoked is the submodule's authenticationProvider and the result is 401 Unauthorized error.
Why the CAS SecurityFilterChain is not invoked? I thought that was handled by Spring Security CAS but it seems not.
I use Spring Security 5.1.2.RELEASE
Thanks a lot for your help.
I found the reason why the CasAuthenticationProvider was not invoked. It's just because of this:
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider" />
</security:authentication-manager>
I changed alias to id.

Spring Security's intercept-url's access="hasRole()" attribute gives error [duplicate]

I have the following snippet
<http use-expressions="true" auto-config="false"
entry-point-ref="loginUrlAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager" disable-url-rewriting="false">
<!--<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter"
/> -->
<custom-filter position="FORM_LOGIN_FILTER"
ref="usernamePasswordAuthenticationFilter" />
<custom-filter position="LOGOUT_FILTER" ref="tapLockFilter" />
<intercept-url pattern="/session/**" access="permitAll" />
<intercept-url pattern="/deviceregistration/**" access="permitAll" />
<intercept-url pattern="/session/lock" access="hasRole('ROLE_MEMBER')" />
<intercept-url pattern="/app/resources/admin*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/app/SuperAppdashboard*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/app/*" access="hasRole('ROLE_MEMBER')" />
<!--<session-management invalid-session-url="/tizelytics/session/invalidSession"
session-authentication-error-url="/tizelytics/session/accessDenied" session-authentication-strategy-ref="sas">
</session-management> -->
<session-management invalid-session-url="/session/invalidSession"
session-authentication-error-url="/session/accessDenied"
session-fixation-protection="none">
<concurrency-control max-sessions="1"
expired-url="/session/accessExpired" />
</session-management>
</http>
When i run this on server it throws an exception saying
Unsupported configuration attributes: [permitAll, permitAll, hasRole('ROLE_ADMIN'), hasRole('ROLE_ADMIN'), hasRole('ROLE_MEMBER'), hasRole('ROLE_MEMBER')]
here is my access-decision-manager bean within the same xml
<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.access.vote.AuthenticatedVoter" />
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
If i remove the access-decision-manager-ref no exception is thrown the app launches correctly can anyone please advice?
Since you are defining your own accessDecisionManager, I don't see WebExpressionVoter as one of the beans in its list. WebExpressionVoter resolves strings like permitAll(), hasRole(), hasAuthority(), etc. So, your accessDecisionManager bean should be:
<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.access.vote.AuthenticatedVoter" />
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
<beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>

Spring Security Pre-Authentication / Login

I did a proof of concept with Spring Security in order to perform pre authentication by using the PRE_AUTH_FILTER filter. It worked OK, but I'd like to know if I can redirect to the login page if the this filter does not work, because I get HTTP 403.
I mean, if the initial request does not contain the SM_USER field in the header, how can I redirect to the login page? I need to consider these two scenarios (when it contains the field - SM_USER -, and when not) and I was not able to get it working. Any ideas about it?
Pra-authentication works smoothly with login authentication in Spring Security. You just setup a working login form configuration, and add the PRE_AUTH_FILTER filter.
Spring only redirects to login page, if after passing the authentication filters, it detects that user is not authenticated when he should be. So if the request contains the expected field in header, the user will be authenticated by the PRE_AUTH_FILTER filter, and will not go to the login page. But if it does not contain one, Spring security will detect a lack of authentication and redirect to login page.
These are my settings:
<http auto-config="true" use-expressions="true" entry-point-ref="http403EntryPoint">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<intercept-url pattern="/accessdenied" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<custom-filter before="PRE_AUTH_FILTER" ref="siteminderFilter" />
<form-login login-page="/login" default-target-url="/list" authentication-failure-url="/accessdenied" />
<logout logout-success-url="/logout" />
</http>
<beans:bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<beans:property name="principalRequestHeader" value="SM_USER"/>
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="exceptionIfHeaderMissing" value="false" />
</beans:bean>
<beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService">
<beans:bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:property name="userDetailsService" ref="customUserDetailsService"/>
</beans:bean>
</beans:property>
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="employeeDAO" />
<authentication-provider ref="preauthAuthProvider" />
</authentication-manager>
<beans:bean id="customUserDetailsService" class="com.test.security.CustomUserDetailsService"></beans:bean>
<beans:bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"></beans:bean>

j_spring_security_check is not available

I upgraded Spring Security from 2 to 3
Previously Security.xml has AuthenticationProcessingFilter and AuthenticationProcessingFilterEntryPoint
So my new Security.xml is
<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.0.3.xsd">
<beans:bean id="userAuthenticationService"
class="com.raykor.core.service.UserAuthenticationService" />
<beans:bean id="shaEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />
<global-method-security />
<http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint">
<intercept-url pattern="/resettingPassword.do**" access="ROLE_ADMIN" />
<intercept-url pattern="/resetPassword.do**" access="ROLE_ADMIN" />
<logout logout-success-url="/index.jsp" invalidate-session="true" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userAuthenticationService">
<password-encoder ref="shaEncoder">
<salt-source user-property="salt" />
</password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="authenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="filterProcessesUrl" value="/j_spring_security_check" />
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureHandler"
ref="failureHandler" />
<beans:property name="authenticationSuccessHandler"
ref="successHandler" />
</beans:bean>
<beans:bean id="successHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="alwaysUseDefaultTargetUrl" value="false" />
<beans:property name="defaultTargetUrl" value="/home.do" />
</beans:bean>
<beans:bean id="failureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.do?error=true" />
</beans:bean>
<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.do" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
`
Also added filter springSecurityFilterChain in web.xml
On login.do it opens Login Page,On Submit it submits to j_spring_security_check with username and password as j_username & j_password
So why is it saying as j_spring_security_checknot avaliable
You instantiate a UsernamePasswordAuthenticationFilter, but it won't be part of the security filter chain just by creating it. Try removing the auto-config="false" from the http config element, and include a <form-login> element within that. I think all the configuration that you have done through the bean definitions can be done using the more concise namespace configuration which should be preferred with Spring Security 3.
I missed to add custom-filter ref i updated
as
<http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint">
<custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter"/>
<intercept-url pattern="/resettingPassword.do**" access="ROLE_ADMIN" />
<intercept-url pattern="/resetPassword.do**" access="ROLE_ADMIN" />
<logout logout-success-url="/index.jsp" invalidate-session="true" />
</http>

Spring Security Ldap remember me not working

I have an application which uses spring security 3.0. The application uses my company's Active directory for login. I borrowed some of the code from the examples on the net and now I am able to successfully perform a bind. But the remember-me functionality is not working. To be more specific, I am able to sign into the application but when I close the browser and open the application it is redirecting to the login page again. Can anyone please tell me what is wrong in my configuration.
Security.xml
<http path-type="regex" use-expressions="true" auto-config="true">
<form-login
login-page="/Login.html"
login-processing-url="/j_spring_security_check"
default-target-url="/home.html"
authentication-failure-url = "/Login.html?login_error=1"
/>
<logout logout-success-url="/Login.html" invalidate-session="true"
delete-cookies="JSESSIONID" />
<intercept-url pattern="\A/Login\Z" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="\A/(?!Login).*\Z" access="isAuthenticated()" />
<remember-me key="_spring_security_remember_me" token-validity-seconds="3600" user-service-ref="ldapUserDetailsService"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="ldapAuthProvider"/>
</authentication-manager>
<beans:bean class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider" id="ldapAuthProvider">
<beans:constructor-arg ref="ldapBindAuthenticator"/>
<beans:property name="userDetailsContextMapper" ref="ldapUserDetailsContextMapper"/>
</beans:bean>
<beans:bean class="org.springframework.security.ldap.DefaultSpringSecurityContextSource" id="ldapServer">
<!-- MS Active Directory -->
<beans:constructor-arg value="ldap://hostname/DC=myCompany,DC=com"/>
<beans:property name="userDn" value="CN=user,OU=Users,DC=mycompany,DC=com"/>
<beans:property name="password" value="xxxxxx"/>
</beans:bean>
<beans:bean class="org.springframework.security.ldap.authentication.BindAuthenticator" id="ldapBindAuthenticator">
<beans:constructor-arg ref="ldapServer"/>
<beans:property name="userSearch" ref="ldapSearchBean"/>
</beans:bean>
<beans:bean class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch" id="ldapSearchBean">
<beans:constructor-arg value="OU=Users"/>
<beans:constructor-arg value="(sAMAccountName={0})"/>
<beans:constructor-arg ref="ldapServer"/>
</beans:bean>
<beans:bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" id="ldapUserDetailsContextMapper"/>
<beans:bean id="ldapUserDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<beans:constructor-arg index="0">
<beans:ref local="ldapSearchBean" />
</beans:constructor-arg>
</beans:bean>
<!-- Bean used for LDAP querying. -->
<beans:bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<beans:constructor-arg ref="ldapServer" />
</beans:bean>
<beans:bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" id="expressionHandler"/>

Resources