I have a BFF setup almost running (it took ages, and has been a very painstaking experience....75+ config files! - and I've not yet persisted anything to a distributed cache yet, in the auth or bff servers).

Anyway, halfway there I think. When the authorization server authorizes, and redirects to the bff server (via a reverse proxy), the bff server gives this error:

java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest is in unnamed module of loader 'app')

I'm not sure what is wrong.

The code can be found here (auth server, reverse proxy, bff server, angular, resource server) https://github.com/dreamstar-enterprises/docs/tree/master/Spring%20BFF

But I think its something to do with the bff server (an OAuthClient)

Also raised on Stack Overflow. https://stackoverflow.com/questions/78802572/spring-gateway-with-spring-auth-resource-server-getting-cors-error https://stackoverflow.com/questions/78809221/spring-gateway-with-bff-parttern-spring-auth-resource-server-linkedhashmap-c

Possibly linked to this issue: https://github.com/spring-projects/spring-security/issues/13971

Can someone help?

Describe the bug A clear and concise description of what the bug is.

To Reproduce Steps to reproduce the behavior.

Expected behavior A clear and concise description of what you expected to happen.

Sample

A link to a GitHub repository with a minimal, reproducible sample.

Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.

Comment From: jzheaux

@dreamstar-enterprises, you've obviously been very hard at work, and I appreciate how you are sticking with it! I'm sorry it's been such a difficult road.

It sounds like this is a question, and those are better suited to StackOverflow, as you have already done. We prefer to use GitHub issues only for bugs and enhancements.

That said, the question you originally posted is about CORS, which is quite far away from the question you posted now. I believe you will get more traction if you post a new question on SO that is focused on the error you are working on, but that is only my opinion.

And as painful as it may sound, you are likely to get to the bottom of the error faster if you can strip away everything that is unnecessary to the reproduction of the problem. Trying to get your head around 75 config files while sussing this out is a challenge for anyone. Once you have it down to the minimum needed, if it looks like there's a bug in Spring Security, please feel free to post a new issue, sharing that sample in the process.

Finally, that specific error is usually a problem with deserialization. Once you've whittled down the cause a bit more, consider reading about Spring Security's Jackson support for additional guidance.

Comment From: dreamstar-enterprises

Thanks Josh, one of the most helpful and encouraging pieces of advice I've receved in weeks. Most people on Stack Overflow batter me on the head, for being a novice with Spring Security - and to use some of the 'unofficial' starter add ons. Whilst really helpful, (via auto config), they don't really help me understand how things work - and whether I'm not double duplicating things, as I need to configure the securitychains to get them to work with Redis... I'll touch base again on whether I can get pased the above bug. Since the error appears in the BFF server log, I'm quite certain it's an issue there

Comment From: dreamstar-enterprises

I've also creaed a separate stack overlfow issue for this: https://stackoverflow.com/questions/78809221/spring-gateway-with-bff-parttern-spring-auth-resource-server-linkedhashmap-c

Comment From: dreamstar-enterprises

I believe it has something to do with this class: WebSessionOAuth2ServerAuthorizationRequestRepository The below happens in the OAuthClient (my BFF) just when it gets the auth code back..

I'm not sure what is means or how to debug it though.

2024-07-30T21:42:17.974+01:00 ERROR 91457 --- [BFF] [ioEventLoop-5-1] a.w.r.e.AbstractErrorWebExceptionHandler : [abd0177c-83]  500 Server Error for HTTP GET "/login/oauth2/code/in-house-auth-server?code=DhgXowJko6ROck4-y3TKyxODh8bk_Le5vjagSc-GwEcbqzBKhYb0nRlnhVDvMumP7yW0oVgbQjdbwE28ZPCuOXOFruhB84YVLWELlTCB48_3lUENN6_89PNOjUeB0Uwx&state=NoN9Yo9xARkebEAwZPIUKfmLkNRWeJCIqrl-J0H--so%3D"

java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest is in unnamed module of loader 'app')
    at org.springframework.security.oauth2.client.web.server.WebSessionOAuth2ServerAuthorizationRequestRepository.lambda$removeAuthorizationRequest$4(WebSessionOAuth2ServerAuthorizationRequestRepository.java:88) ~[spring-security-oauth2-client-6.3.1.jar:6.3.1]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ OidcSessionRegistryAuthenticationWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ OAuth2AuthorizationRequestRedirectWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ ReactorContextWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ CsrfWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ OidcBackChannelLogoutWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ OidcSessionRegistryWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ HttpHeaderWriterWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
    *__checkpoint ⇢ HTTP GET "/login/oauth2/code/in-house-auth-server?code=DhgXowJko6ROck4-y3TKyxODh8bk_Le5vjagSc-GwEcbqzBKhYb0nRlnhVDvMumP7yW0oVgbQjdbwE28ZPCuOXOFruhB84YVLWELlTCB48_3lUENN6_89PNOjUeB0Uwx&state=NoN9Yo9xARkebEAwZPIUKfmLkNRWeJCIqrl-J0H--so%3D" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at org.springframework.security.oauth2.client.web.server.WebSessionOAuth2ServerAuthorizationRequestRepository.lambda$removeAuthorizationRequest$4(WebSessionOAuth2ServerAuthorizationRequestRepository.java:88) ~[spring-security-oauth2-client-6.3.1.jar:6.3.1]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:132) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:113) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:224) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:224) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1865) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.signalCached(MonoCacheTime.java:337) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.onNext(MonoCacheTime.java:354) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.innerNext(FluxConcatMapNoPrefetch.java:259) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:865) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:158) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2097) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:145) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredComplete(FluxUsingWhen.java:397) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:532) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:828) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:612) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:592) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:469) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxArray$ArraySubscription.slowPath(FluxArray.java:137) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxArray$ArraySubscription.request(FluxArray.java:99) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:373) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxMerge.subscribe(FluxMerge.java:73) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4568) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onComplete(FluxUsingWhen.java:389) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:850) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:612) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.innerComplete(FluxFlatMap.java:898) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxFlatMap$FlatMapInner.onComplete(FluxFlatMap.java:1001) ~[reactor-core-3.6.8.jar:3.6.8]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144) ~[reactor-core-3.6.8.jar:3.6.8]
        at io.lettuce.core.RedisPublisher$ImmediateSubscriber.onComplete(RedisPublisher.java:900) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.RedisPublisher$State.onAllDataRead(RedisPublisher.java:702) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.RedisPublisher$State$3.read(RedisPublisher.java:612) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.RedisPublisher$State$3.onDataAvailable(RedisPublisher.java:569) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.RedisPublisher$RedisSubscription.onDataAvailable(RedisPublisher.java:326) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.RedisPublisher$RedisSubscription.onAllDataRead(RedisPublisher.java:341) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.RedisPublisher$SubscriptionCommand.doOnComplete(RedisPublisher.java:782) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.protocol.CommandWrapper.complete(CommandWrapper.java:65) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.protocol.CommandWrapper.complete(CommandWrapper.java:63) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:745) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:680) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:597) ~[lettuce-core-6.3.2.RELEASE.jar:6.3.2.RELEASE/8941aea]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1473) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1336) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1385) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530) ~[netty-codec-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469) ~[netty-codec-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994) ~[netty-common-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.111.Final.jar:4.1.111.Final]
        at java.base/java.lang.Thread.run(Thread.java:1623) ~[na:na]