spring-projects / spring-projects/spring-security

Session authentication strategy is not called after successfully authentication

Open
#4,212 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Summary

Session authentication strategy is not called after a successfully authentication.

I have used the standard strategy against session fixation, but this is not called.

Actual Behavior

This issue appears if:

  1. The user makes a regular request and get a session.
  2. The user makes a regular second request with this session.
  3. The user makes a authentication with this session.

As a result:
Session authentication strategy is not called after successfully authentication.

Expected Behavior

Session authentication strategy is called after successfully authentication.

Configuration

I have configured spring security with the default filter chain (normal order)

Special to mention for the described error:
I use the org.springframework.security.web.context.SecurityContextPersistenceFilter as the first filter in the chain.
I have used the standard SessionManagementFilter (which is configured with SessionFixationProtectionStrategy).

Version

4.2.1 RELEASE

Details of the cause

I have debugged the behavior and I think I have found the root cause.

After the filter chain was proceeded the SecurityContextPersistenceFilter invoke a saveContext on the configured SecurityContextRepository. (this happens every time and is located in a finally block).
As you can see here:

SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
try {
	SecurityContextHolder.setContext(contextBeforeChainExecution);

	chain.doFilter(holder.getRequest(), holder.getResponse());

}
finally {
	SecurityContext contextAfterChainExecution = SecurityContextHolder
			.getContext();
	// Crucial removal of SecurityContextHolder contents - do this before anything
	// else.
	SecurityContextHolder.clearContext();
	repo.saveContext(contextAfterChainExecution, holder.getRequest(),
			holder.getResponse());
	request.removeAttribute(FILTER_APPLIED);

	if (debug) {
		logger.debug("SecurityContextHolder now cleared, as request processing completed");
	}
}

The standard implementation of the repository is the HttpSessionSecurityContextRepository. This one saves a given security context to the session. In this case this is a SecurityContext with an null authentication inside. (will be result from repo.loadContext(holder) if there is no context yet).

This happens on each normal requests. (it seems that this mechanism don't make a session for itself but the state is saved is there was a given session in the request)

So if there was some normal requests there is an empty (not null) security context in the session.

And if this is the case the logic of SessionManagementFilter will not work properly.
The configured session authentication strategy will only invoke if the following if statement is true:

if (!securityContextRepository.containsContext(request)) {

This function just checks if there is something in the session and is not null

public boolean containsContext(HttpServletRequest request) {
		HttpSession session = request.getSession(false);

		if (session == null) {
			return false;
		}

		return session.getAttribute(springSecurityContextKey) != null;
	}

But there is an empty not null security context in the session and so the logic inside the if will not be executed and no session invalidation will be invoked.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the request sequence with SecurityContextPersistenceFilter, SessionManagementFilter, SessionFixationProtectionStrategy, and HttpSessionSecurityContextRepository configured as described. Trace how the repository saves and detects the security context across requests, then verify that the session authentication strategy is invoked after authentication even when an earlier request created an empty context.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
authentication, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.