Expected Behavior
When using Spring Security OAuth2 Client, even if we misconfigured the user info endpoint which result in an OAuth2AuthenticationException, the exception should be processed instead of an internal error which result in HTTP status 500.
Current Behavior
When using Spring Security OAuth2 Client, if a wrong user info endpoint which response contains invalid content type 'text/html' is configured, an OAuth2AuthenticationException will be thrown in the process of oauth callback request, if we use Spring Data session redis at the same time, an SerializationException will be thrown:
2023-09-06 15:20:07,322 [http-nio-8081-exec-4] WARN [org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver] [ExceptionHandlerExceptionResolver.java:434] [trace=9ac654b769f4296f,span=9ac654b769f4296f][tenant=javaapptest,region=] [TID: N/A] - Failure in @ExceptionHandler com.zatech.octopus.component.exception.resolver.MessageSourceExceptionHandler#handler(Throwable, HttpServletRequest, HttpServletResponse)
org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:96)
at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:186)
at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:209)
at org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:187)
at org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.saveDelta(RedisIndexedSessionRepository.java:811)
at org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.save(RedisIndexedSessionRepository.java:799)
at org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.access$000(RedisIndexedSessionRepository.java:686)
at org.springframework.session.data.redis.RedisIndexedSessionRepository.save(RedisIndexedSessionRepository.java:415)
at org.springframework.session.data.redis.RedisIndexedSessionRepository.save(RedisIndexedSessionRepository.java:251)
at org.springframework.cloud.sleuth.instrument.session.TraceSessionRepository.lambda$save$1(TraceSessionRepository.java:74)
at org.springframework.cloud.sleuth.instrument.session.TraceSessionRepository.lambda$wrap$0(TraceSessionRepository.java:63)
I'm not sure what cause the OAuth2AuthenticationException cannot be serialized, the OAuth2AuthenticationException looks like this:
Context
A sample to reproduce the issue can be found here: https://github.com/wapkch/spring-security-oauth2-client-demo
spring:
security:
oauth2:
client:
registration:
azure:
client-id:
client-secret:
authorization-grant-type: authorization_code
scope: openid,profile
redirect-uri: http://localhost:8080/login/oauth2/code/callback
provider:
azure:
authorization-uri:
token-uri:
user-info-uri: https://www.google.com # Intentionally configured incorrectly
user-name-attribute: preferred_username
jwk-set-uri:
- Fill in the blank configs,
- Start the application
- Access
http://localhost:8081/
Then we can reproduce:
And the log:
2023-09-06 15:20:07,322 [http-nio-8081-exec-4] WARN [org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver] [ExceptionHandlerExceptionResolver.java:434] [trace=9ac654b769f4296f,span=9ac654b769f4296f][tenant=javaapptest,region=] [TID: N/A] - Failure in @ExceptionHandler com.zatech.octopus.component.exception.resolver.MessageSourceExceptionHandler#handler(Throwable, HttpServletRequest, HttpServletResponse)
org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:96)
at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:186)
at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:209)
at org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:187)
at org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.saveDelta(RedisIndexedSessionRepository.java:811)
at org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.save(RedisIndexedSessionRepository.java:799)
at org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.access$000(RedisIndexedSessionRepository.java:686)
at org.springframework.session.data.redis.RedisIndexedSessionRepository.save(RedisIndexedSessionRepository.java:415)
Comment From: marcusdacoregio
Hi, @wapkch. Unfortunately, I have not been able to reproduce the error. Can you provide a minimal, reproducible sample that has everything that we need to reproduce it? You can use the Spring Authorization Server and the Testcontainers support in Spring Boot to make it easier to run.
Comment From: wapkch
Hi, @marcusdacoregio Thanks for reply. I have updated the demo. The issue can be reproduced by the following steps:
1. Start the application using com.example.springsecurityoauth2clientdemo.SpringSecurityOauth2ClientDemoApplicationTests#main
2. Access http://127.0.0.1:8080/sso using a web browser
3. login with username/password (user1/password)
4. The issues can be produced.
Comment From: marcusdacoregio
Related https://github.com/spring-projects/spring-framework/issues/31283
Comment From: marcusdacoregio
Hi, @wapkch. This has been resolved as part of https://github.com/spring-projects/spring-framework/issues/31283, available in Spring Framework 6.0.13. Thank you.