I am using a Spring security 3.X on the client side and CAS 4.0 on the server.
When i am doing CAS+Spring security integration, I am able to reach the level of ticket validation success and able to get the proper roles at the client side.
But I have added the following lines in my casServiceValidationSuccess.jsp to iterate and send the attributes in my response as my attributes are not released properly:
<cas:attributes>
<cas:user>${fn:escapeXml(assertion.primaryAuthentication.principal.id)}</cas:user>
<c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">
<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>
</c:forEach>
</cas:attributes>
So wants to know is there any other alternative changes to do in deployerConfigContext.xml in the CAS server side to release particular attribute-"authorities" in my case and to get the same in SPRING client side.
Find the snippets of existing deployerConfigContext.xml where trying to release "authorities" attributes:
<bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
<constructor-arg>
<map>
<entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
</map>
</constructor-arg>
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="SELECT EMAIL FROM USER_DATA WHERE UserID = ?" />
</bean>
<bean id="primaryPrincipalResolver"
class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</bean>
<bean id="attributeRepository"
class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="dataSource" />
<constructor-arg index="1" value="SELECT UserID, UserROLES FROM USER_DATA WHERE {0}" />
<property name="queryAttributeMapping">
<map>
<entry key="username" value="UserID" />
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="UserID" value="username" />
<entry key="UserROLES" value="UserROLES" />
</map>
</property>
</bean>
<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<property name="registeredServices">
<list>
<bean class="org.jasig.cas.services.RegisteredServiceImpl">
<property name="id" value="0"></property>
<property name="name" value="HTTP"></property>
<property name="description" value="Only Allows HTTP Urls"></property>
<property name="serviceId" value="http://**" />
<property name="usernameAttribute" value="username" />
<property name="ignoreAttributes" value="false" />
<property name="allowedAttributes">
<list>
<value>UserROLES</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
Also find the security-context.xml at the spring client side:
<security:http use-expressions="true" entry-point-ref="casAuthenticationEntryPoint"
auto-config="true">
<security:custom-filter position="CAS_FILTER"
ref="casAuthenticationFilter"></security:custom-filter>
<security:intercept-url pattern="/home" access="hasRole('ROLE_TEST')"></security:intercept-url>
<security:intercept-url pattern="/**" access="hasRole('ROLE_ANONYMOUS')"></security:intercept-url>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="casAuthenticationProvider"></security:authentication-provider>
</security:authentication-manager>
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service"
value="http://localhost:7080/test/j_spring_cas_security_check"></property>
<property name="sendRenew" value="false"></property>
</bean>
<bean id="casAuthenticationFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"></property>
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="http://localhost:8090/cas-server-webapp-4.0.0/login"/>
</bean>
</property>
<property name="authenticationSuccessHandler">
<bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/home.jsp"/>
</bean>
</property>
</bean>
<bean id="casAuthenticationEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl"
value="http://localhost:8090/cas-server-webapp-4.0.0/login"></property>
<property name="serviceProperties" ref="serviceProperties"></property>
</bean>
<!-- Handles the CAS ticket processing. -->
<bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<!-- <property name="userDetailsService" ref="userService"></property> -->
<property name="authenticationUserDetailsService" ref="authenticationUserDetailsService" />
<property name="serviceProperties" ref="serviceProperties"></property>
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0"
value="http://localhost:8090/cas-server-webapp-4.0.0">
</constructor-arg>
</bean>
</property>
<property name="key" value="cas"></property>
</bean>
<bean id="authenticationUserDetailsService"
class="org.springframework.security.cas.userdetails.GrantedAuthorityFromAssertionAttributesUserDetailsService">
<constructor-arg>
<list>
<value>UserROLES</value>
</list>
</constructor-arg>
</bean>
</beans>
Disclaimer: I'm the Chairman of CAS and founder of CAS in the cloud (https://www.casinthecloud.com).
Is your attribute person DAO referenced by your authentication handler? Does it work without Spring security doing a manual service ticket validation?
Related
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="${models.DS_POOL_NAME}" />
</property>
</bean>
<bean id="DBPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="properties">
<bean class="org.apache.commons.configuration2.ConfigurationConverter" factory-method="getProperties">
<constructor-arg>
<bean id="DatabaseConfigurator" class="org.apache.commons.configuration2.DatabaseConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="table" value="sample" />
<property name="keyColumn" value="PROPERTY" />
<property name="valueColumn" value="VALUE" />
<property name="configurationNameColumn" value="GROUP_NAME" />
<property name="configurationName" value="new" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
when we ref dataSource in DBPlaceholder bean then ${models.DS_POOL_NAME} will showing error because this value is coming from properties
Has anybody done spring pre-authentication with TAM Web-seal?
Can you please share the configuration details?
If webseal forward the request with the username in iv-user header, then it is relative simple to configure spring-security:
<security:http auto-config="false" use-expressions="true" entry-point-ref="authenticationEntryPoint" access-decision-manager-ref="httpAccessDecisionManager">
<security:custom-filter ref="webSealPreAuthFilter" position="PRE_AUTH_FILTER"/>
...
</security:http>
<bean id="webSealPreAuthFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="principalRequestHeader" value="iv-user"/>
<!-- exceptionIfHeaderMissing AND checkForPrincipalChanges needs to be enable to check that each request needs a "iv-user" header -->
<property name="checkForPrincipalChanges" value="true"/>
<property name="exceptionIfHeaderMissing" value="true"/>
</bean>
<alias name="authenticationManager" alias="org.springframework.security.authenticationManager"/>
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<property name="authenticationEventPublisher">
<bean class="org.springframework.security.authentication.DefaultAuthenticationEventPublisher"/>
</property>
<constructor-arg name="providers">
<list>
<ref local="preAuthenticatedAuthenticationProvider"/>
</list>
</constructor-arg>
</bean>
<bean id="preAuthenticatedAuthenticationProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<constructor-arg name="userDetailsService" ref="userDetailsService"/>
</bean>
</property>
</bean>
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
You need an userDetailsService but this is highly dependend on how your application works.
I have two file types to insert in database.
Format are : aa;bb;cc and aa;bb;cc;dd;ee
This is my FlatFileItemReader :
<bean name="readerContractToAddIntoPRV" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="comments" value="#" />
<property name="linesToSkip" value="1" />
<property name="strict" value="false" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="fieldSetMapper">
<bean class="net.wl.batchs.fieldSetMapper.LineToCreateIntoPrvFieldSetMapper" />
</property>
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value=";"/>
<property name="names" value="aa,bb,cc,dd,ee" />
</bean>
</property>
</bean>
</property>
</bean>
I want a setup that works for both types of files.
For the moment, I have this :
org.springframework.batch.item.file.transform.IncorrectTokenCountException:
Incorrect number of tokens found in record: expected 3 actual 5
Do you have any ideas?
Thank you.
Edit : After correction :
<bean name="readerContractToAddIntoPRV" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="comments" value="#" />
<property name="linesToSkip" value="1" />
<property name="strict" value="false" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper" p:lineTokenizer-ref="multilineFileTokenizer">
<property name="fieldSetMapper">
<bean class="net.wl.batchs.fieldSetMapper.LineToCreateIntoPrvFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="multilineFileTokenizer" class="org.springframework.batch.item.file.transform.PatternMatchingCompositeLineTokenizer">
<property name="tokenizers">
<map>
<entry key="*;*;*;*;*" value-ref="NSCE_ICCID_MSISDN_LOGIN_PWD"/>
<entry key="*;*;*" value-ref="NSCE_ICCID_MSISDN"/>
<entry key="*" value-ref="headerDefault"/>
</map>
</property>
</bean>
<bean id="parentLineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer" abstract="true">
<property name="delimiter" value=";"/>
</bean>
<bean id="NSCE_ICCID_MSISDN_LOGIN_PWD" parent="parentLineTokenizer">
<property name="names" value="nsce,iccid,msisdn,login,pwd" />
</bean>
<bean id="NSCE_ICCID_MSISDN" parent="parentLineTokenizer">
<property name="names" value="nsce,iccid,msisdn" />
</bean>
<bean id="headerDefault" parent="parentLineTokenizer">
<property name="names" value="nsce,iccid,msisdn" />
</bean>
The issue isn't your tokenizer. What you'll have to do is use the PatternMatchingCompositeLineMapper (http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/item/file/mapping/PatternMatchingCompositeLineMapper.html). This will allow you to create a pattern for each line type you have and associate it with the appropriate LineTokenizer.
You can see this LineMapper in action in our samples here: https://github.com/spring-projects/spring-batch/blob/master/spring-batch-samples/src/main/resources/jobs/multilineOrderInputTokenizers.xml
I have a spring mvc webapp with spring batch built into it. I am having some issues getting my spring batch jobs to be launchable in the spring batch admin console. This is what I see when I go to the jobs page...
All of my jobs are coming up as launchable=false. I was wondering how I can fix this. I read some documentation about why this would be so and it said that I need to use a AutomaticJobRegistrar.
I tried this but it didn't change anything. I've put my spring batch job configuration below. Would appreciate it someone could tell me what is missing.
thanks
<beans profile="pre,prod">
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
parent="abstractCustDbJdbcDao">
<property name="transactionManager" ref="custDbTransactionManager" />
<property name="databaseType" value="db2" />
<property name="tablePrefix" value="REPMAN.BATCH_" />
</bean>
<bean id="jobExplorer"
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
parent="abstractCustDbJdbcDao" />
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
<bean id="jobLoader" class="org.springframework.batch.core.configuration.support.AutomaticJobRegistrar">
<property name="applicationContextFactories">
<bean class="org.springframework.batch.core.configuration.support.ClasspathXmlApplicationContextsFactoryBean">
<property name="resources" value="classpath*:/META-INF/spring/jobs/*.xml" />
</bean>
</property>
<property name="jobLoader">
<bean class="org.springframework.batch.core.configuration.support.DefaultJobLoader">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
</property>
</bean>
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="dailyTranCountJobDetail" />
<ref bean="bulletinBarMsgUpdateJobDetail" />
<ref bean="updateLovCacheJobDetail" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="dailyTranCountCronTrigger" />
<ref bean="bulletinBarMsgUpdateCronTrigger" />
<ref bean="updateLovCacheCronTrigger" />
</list>
</property>
</bean>
<!-- scheduling properties -->
<util:properties id="batchProps" location="classpath:batch.properties" />
<context:property-placeholder properties-ref="batchProps" />
<!-- triggers -->
<bean id="dailyTranCountCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="dailyTranCountJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.dailyTranCounts']}" />
</bean>
<bean id="bulletinBarMsgUpdateCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="bulletinBarMsgUpdateJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.bulletinBarUpdateMsg']}" />
</bean>
<bean id="updateLovCacheCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="updateLovCacheJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.updateLovCache']}" />
</bean>
<!-- job detail -->
<bean id="dailyTranCountJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-daily-tran-counts" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean id="bulletinBarMsgUpdateJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-bulletin-bar-msg-update" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean id="updateLovCacheJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-update-lov-cache" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
</beans>
There are a few things this could be:
Where is the XML file you reference above located? It needs to be the META-INF/spring/batch/jobs directory in your WAR file (that's where Spring Batch Admin will look).
Don't configure common components in your XML file. That includes the jobLauncher, jobRepository, jobExplorer, jobLoader, or jobRegistry. That being said, I don't see an actual job defined in your XML file. The XML file needs one of those ;)
You can read more about adding your own job definitions to Spring Batch Admin: http://docs.spring.io/spring-batch-admin/reference/jobs.html#Add_your_Own_Jobs_For_Launching_in_the_UI
I'm using Spring Security 3.1 and I'm facing a problem with session time outs.
I've set session time-out in the web.xml as follows:
<session-config>
<session-timeout>
45
</session-timeout>
</session-config>
So session is supposed to be expired after 45 minutes.
However I've noticed that session is expired exactly after 2 minutes! Whether I'm working with application or not.
These are my spring security beans:
<bean id="ConcurrentSessionFilterAdmin" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<property name="sessionRegistry" ref="sessionRegistry"/>
<property name="logoutHandlers">
<list>
<ref bean = "logoutHandler"/>
</list>
</property>
<property name="expiredUrl" value="/admin/login.jsp?error=expiredURL"/>
</bean>
<bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" autowire="byType" />
<bean id="logoutHandler"
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name="securityContextRepository" ref="securityContextRepository"/>
</bean>
<bean id="securityContextRepository"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository">
<property name="allowSessionCreation" value="false" />
</bean>
<bean id="logoutFilterAdmin"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="/admin/login.jsp" />
<constructor-arg>
<list>
<ref bean="logoutHandler"/>
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/admin/j_spring_security_logout"></property>
</bean>
<bean id="usernamePasswordAuthenticationFilterAdmin"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="usernameParameter" value="j_username"/>
<property name="passwordParameter" value="j_password"/>
<property name="allowSessionCreation" value="false"/>
<property name="authenticationFailureHandler" ref="authenticationFailureHandlerAdmin"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="authenticationSuccessHandlerAdmin"/>
<property name="continueChainBeforeSuccessfulAuthentication" value="false"/>
<property name="filterProcessesUrl" value="/admin/j_spring_security_check"/>
<property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy"/>
</bean>
<bean id="authenticationFailureHandlerAdmin"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/admin/login.jsp?error=loginfailed" />
</bean>
<bean id="authenticationSuccessHandlerAdmin"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="requestCache" ref="requestCache"/>
<property name="defaultTargetUrl" value="/admin/index.html"/>
</bean>
<bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache"/>
<bean id="sessionAuthenticationStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<property name="maximumSessions" value="1" />
<property name="migrateSessionAttributes" value="true"/>
</bean>
<bean id="basicAuthenticationFilterAdmin"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationDetailsSource" ref="authenticationDetailsSource"/>
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean id="authenticationDetailsSource"
class="org.springframework.security.authentication.AuthenticationDetailsSourceImpl"/>
<bean id="requestCacheAwareFilter"
class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter">
<constructor-arg ref="requestCache"/>
</bean>
<bean id="securityContextHolderAwareRequestFilter"
class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter">
<property name="rolePrefix" value="ROLE_"/>
</bean>
<bean id="anonymousAuthenticationFilter"
class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<constructor-arg value="KEY"/>
</bean>
<bean id="sessionManagementFilterAdmin" class="org.springframework.security.web.session.SessionManagementFilter">
<constructor-arg ref="securityContextRepository"/>
<constructor-arg ref="sessionAuthenticationStrategy"/>
<property name="authenticationFailureHandler" ref="authenticationFailureHandlerAdmin"/>
<property name="invalidSessionStrategy" ref="invalidSessionStrategyAdmin"/>
</bean>
<bean id="invalidSessionStrategyAdmin"
class="org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy">
<constructor-arg value="/admin/login.jsp"/>
<property name="createNewSession" value="false"/>
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
<property name="requestCache" ref="requestCache"/>
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint">
</bean>
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
</bean>
<bean id="filterSecurityInterceptorAdmin"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="securityMetadataSource" ref="myFilterInvocationSecurityMetadataSource" />
</bean>
<bean id="myFilterInvocationSecurityMetadataSource" class="com.datx.security.model.MyFilterSecurityMetadataSource" autowire="byName" scope="prototype">
</bean>
After two minutes, I'm redirected to /admin/login.jsp?error=expiredURL which is set in the first bean configuration. (Which means session is expired)
The question is which of these beans are responsible for session expiration? What property haven't I set that causes this problem?
Spring Security relies on the underlying container, i.e. it's the container who manages session timeouts(please add information about the container you're using). However, I believe that web.xml settings usually should have a bigger priority if the server is Java EE compliant.
Also individual session timeouts can be tweaked dynamically by calling HttpSession.setMaxInactiveInterval() method, or the session can be invalidated by calling invalidate().
It's possible for Spring Security to invalidate session in some cases (for example, after logging in, the user gets a new HttpSession).
Also session invalidation can be caused by Spring Security concurrent-session control mechanism, for example if the max-sessions value is specified.
You can check when Spring Security invalidates the session by setting DEBUG logging level for org.springframework.security.* namespace, as Spring typically writes such info to the logger.