Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AwsHttpServletRequest throws UnsupportedOperationException in getRequestedSessionId instead of returning null #111

Closed
kdhunter opened this issue Jan 30, 2018 · 8 comments

Comments

@kdhunter
Copy link

  • Framework version: 0.9
  • Implementations: Spring Boot

Using aws-serverless-java-container-spring 0.9 and Spring Boot 1.5.9.RELEASE, which pulls in Spring Security 4.2.3.RELEASE.

The current implementation of com.amazonaws.serverless.proxy.internal.servlet.AwsHttpServletRequest throws an UnsupportedOperationException when the getRequestedSessionId() method is called.

The default Spring Boot configuration includes the Spring Security SessionManagementFilter in the filter chain. The problem is that the SessionManagementFilter checks the requested session ID under some scenarios:

From org.springframework.security.web.session.SessionManagementFilter, starting at line 118 in doFilter:

			else {
				// No security context or authentication present. Check for a session
				// timeout
				if (request.getRequestedSessionId() != null
						&& !request.isRequestedSessionIdValid()) {
					if (logger.isDebugEnabled()) {
						logger.debug("Requested session ID "
								+ request.getRequestedSessionId() + " is invalid.");
					}

					if (invalidSessionStrategy != null) {
						invalidSessionStrategy
								.onInvalidSessionDetected(request, response);
						return;
					}
				}

Thus, the call to request.getRequestedSessionId() throws and the exception then propagates through the system, destroying the request.

If getRequestedSessionId() returned null, instead of throwing an exception, this problem wouldn't occur.

A null return value from getRequestedSessionId() indicates that the user did not specify a session ID. This would be consistent with the fact that isRequestedSessionIdValid() returns false, and in conformance with the HttpServletRequest specification.

@kdhunter
Copy link
Author

Neglected to mention that it appears that you can work around this by completely disabling session management:

@EnableWebSecurity  
public class TestSiteSecurity extends WebSecurityConfigurerAdapter { 
    @Override  
    protected void configure(HttpSecurity http) throws Exception {  
        http.sessionManagement().disable();
     } 
}

which prevents the SessionManagmentFilter from being added to the chain. Our preferred configuration was

http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

which tells Spring never to create a session. However this configuration keeps the SessionManagementFilter in the Spring filter chain, with the effect noted above.

@sapessi
Copy link
Collaborator

sapessi commented Jan 30, 2018

Thanks for the feedback @kdhunter. Throwing that exception was a deliberate choice. Writing applications with Lambda, we expect you not to rely on a session - your code needs to be completely stateless. I will definitely include your snippet on how to disable session checking in the Spring Boot docs.

If this is something you want to leverage, can you tell me a little bit more about the use-case and what you are trying to achieve? I'll see if there's anything we can do.

@kdhunter
Copy link
Author

kdhunter commented Jan 31, 2018 via email

sapessi added a commit that referenced this issue Jan 31, 2018
… bug introduced with the fixes for #84. Added unit tests
@sapessi
Copy link
Collaborator

sapessi commented Jan 31, 2018

@kdhunter fair point. Would returning null from the getSessionId() call work here? I can make the change today and push it out in the 0.9.1 release.

@sapessi sapessi added this to the Release 0.9.1 milestone Jan 31, 2018
@sapessi
Copy link
Collaborator

sapessi commented Jan 31, 2018

I've just tested returning from the getRequestSessionId() method, the security framework then moves on to requesting the session - which would throw the exception. If I return a non-null value, it proceeds trying to cache the session in an internal class. I'm not sure there's a clean and safe way around this. I'm no spring expert so open to suggestions. Given the above, I'd rather update the documentation to reflect the required security configuration for spring and not change the framework (throw the UnsupportedOperationException everywhere).

@sapessi sapessi added the docs label Jan 31, 2018
@sapessi sapessi removed this from the Release 0.9.1 milestone Jan 31, 2018
sapessi added a commit that referenced this issue Jan 31, 2018
…g log messages in request object when a framework tries to access the session
@kdhunter
Copy link
Author

kdhunter commented Feb 1, 2018

In my particular case, things were blowing up at the point in the code that I posted - I didn’t get any farther, so it’s very possible that I could have run into trouble later even if getRequestSessionId had returned null. I had configured my application to be “stateless" - I had assumed (possibly incorrectly) that nothing would then attempt to create a session.

@Override
  protected void configure(HttpSecurity http) throws Exception {
        http
          .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }
}

Possibly that's incorrect without the additional configuration - as I said, I didn't get farther than the code I posted earlier.

I absolutely agree that including explicit documentation as to how you need to set up Spring Security would be a tremendous help for others that might run into similar problems.

All that being said, I still kind of think that having getRequestSessionId return null and have the exception being thrown from getSession() or getSession(true) feels “more correct." In my opinion, it would better draw attention to exactly what it is that you were trying to prevent (the creation of an HttpSession when sessions aren't supported). Throwing an UnsupportedOperationException from getSession that says "sessions aren't supported in this environment" would (to me at least) pretty explicitly explain that. It would also better draw attention to the offending portion of whatever code was triggering the attempted session creation so that people would have a better idea how to work around it. With the current implementation, I was forced to kind of infer your intent.

Just my $0.02.

@sapessi
Copy link
Collaborator

sapessi commented Feb 1, 2018

Thanks @kdhunter, makes sense to me to return null on the session id and throw the exception when the framework tries to explicitly get/create a session. I will make this change for the next release. I will update the documentation to include the spring security settings today.

@sapessi sapessi added this to the Release 1.0 milestone Feb 1, 2018
@sapessi
Copy link
Collaborator

sapessi commented Feb 13, 2018

Changes are done and committed to the core branch of the codebase. They will go out officially with the 1.0 release.

@sapessi sapessi closed this as completed Feb 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants