spring-projects / spring-projects/spring-security

Session Management filter does not seem to honor the require explicit save option -> securityContext .requireExplicitSave(true)

Open
#14,675 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Describe the bug
SessionManagementFilter does not seem to honor the require explicit save option - securityContext .requireExplicitSave(true) and saves the authenticated security context to session.

The require explicit save option is supposed to be used for cases where session management is required, but, authorization comes from a stateless option like a token. But, as part of the fix for SEC-1396 (https://github.com/spring-projects/spring-security/issues/1639), the saveContext is done without considering the option.

To Reproduce

  1. Configure HTTP to use requireExplicitSave as true, to have securityContext not saved to session
  2. Configure spring to issue JWT token on login
  3. Authenticate into the application
  4. Call any of the URLs requiring authentication with JSESSIONID, but without the token

Expected behavior
The request should fail as unauthorized, since no token is passed

Workaround

Since SessionManagementFilter could not be easily overridden, only workaround seems to be to extend the SecurityContextRepository and override saveContext and containsContext as below, so as to handle the case where the SessionManagementFilter knows that the authentication was done in an earlier request and not authenticate again, without storing the security context.

http.setSharedObject(SecurityContextRepository.class,
                new HttpSessionSecurityContextRepository() {
					@Override 
					public void saveContext(org.springframework.security.core.context.SecurityContext context, HttpServletRequest request, HttpServletResponse response) {
						super.saveContext(context, request, response);
						if (request.getSession(false) != null) {
							request.getSession(false).removeAttribute(this.SPRING_SECURITY_CONTEXT_KEY);
							request.getSession(false).setAttribute("SPRING_WORKAROUND_AUTH_COMPLETE", "true");
						}
					}
					
					@Override
					public boolean containsContext(HttpServletRequest request) {
						HttpSession session = request.getSession(false);
						if (session == null) {
							return false;
						}
						return session.getAttribute("SPRING_WORKAROUND_AUTH_COMPLETE") != null;
					}
					
				});

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 with SessionManagementFilter and trace how requireExplicitSave(true) is handled through SecurityContextRepository, especially saveContext and containsContext. Reproduce the JWT and JSESSIONID sequence described in the issue; done means the request without a token is unauthorized and the authenticated context is not saved to the session.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.