Summary

I was trying to get Security Context in my WebFilter as you would typically do it:

chain.filter(exchange)
    .subscriberContext(context -> {
        context.getKey(SecurityContext.class);
        //some work on context
    });

Actual Behavior

Calling context.get(SecurityContext.class) causes java.util.NoSuchElementException: Context does not contain a value of type org.springframework.security.core.context.SecurityContext even though context.hasKey(SecurityContext.class) returns true (since ReactorContextWebFilter::withSecurityContext merges SecurityContext into Context). The thing is, security context is present within the Context, but wrapped in Mono (see ServerSecurityContextRepository::load which returns mono, not SecurityContext).

The same issue makes ReactiveSecurityContextHolder::getContext() useless in WebFilters. It tries to load context just as i did in my filter and fails:

    public static Mono<SecurityContext> getContext() {
        return Mono.subscriberContext()
            .filter( c -> c.hasKey(SECURITY_CONTEXT_KEY))
            .flatMap( c-> c.<Mono<SecurityContext>>get(SECURITY_CONTEXT_KEY));
    }

Expected Behavior

context.get(SecurityContext.class) returns SecurityContext or Mono<SecurityContext>, not thows an exception.

Configuration

Version

5.0.5.RELEASE

Sample

Filter below would cause an unexpected exception:

@Component
@Order(2)
public class SecurityContextExctractingFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return chain.filter(exchange)
                .subscriberContext(context -> {
                            if (context.hasKey(SecurityContext.class)) {
                                SecurityContext secContext = context.get(SecurityContext.class);
                            }
                            return context.put("SomeString", "SomeObject");
                        }
                );
    }
}

Comment From: Sobakaa

Turns out i wasn't supplying a type properly. Using context.<Mono<SecurityContext>>get(SecurityContext.class) solves the issue. ReactiveSecurityContextHolder::getContext() not working properly is, again, a misuse on my side.

Comment From: Nida96

Can you elaborate your solution? As I too am facing this issue. specifically how are you making the getContext() call now.