Please support auto-configuring the JwtDecoderConfiguration for non-web environment.
Currently the config is imported from OAuth2ResourceServerAutoConfiguration with
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
But configuration of JwtDecoderConfiguration is not tied to WEB environment anyhow.
This will allow to use authentication provider for BearerTokenAuthenticationToken in other environments , like grpc server for example.
This used to work with 2.6.6 untill the behavior of
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
was fixed.
Back-porting this to 2.6.x will also be great.
Thanks
Comment From: mbhave
@jvmlet Can you please clarify what you mean by the following?
This used to work with 2.6.6 until the behavior of @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) was fixed.
I tried it with 2.6.5 and see the same behavior, i.e, JwtDecoder being configured only if the web environment is servlet.
While JwtDecoder might be useful in non-web applications, we auto-configure it so that it can be used by the JwtConfigurer which gets configured by a SecurityFilterChain.
I'm not sure if separating the JwtDecoder out adds much benefit to users looking to add it outside of web applications.
Flagging for team-attention to see wha the rest of the team thinks.
Comment From: jvmlet
@mbhave , thanks for your reply.
I tried it with 2.6.5 and see the same behavior, i.e, JwtDecoder being configured only if the web environment is servlet.
Here is autoconfiguration report with 2.6.6 :
OAuth2ResourceServerAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken' (OnClassCondition)
- found 'session' scope (OnWebApplicationCondition)
and here is with 2.6.8
OAuth2ResourceServerAutoConfiguration:
Did not match:
- not a servlet web application (OnWebApplicationCondition)
Matched:
- @ConditionalOnClass found required class 'org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken' (OnClassCondition)
This can be reproduced by running this test (and tweaking properties file + adding DEBUG=true env variable.)
I understand that SecurityFilterChain is tied to web environment and relays on JwtDecoder , but the benefit is that in the GRPC world (or any other hosting mean, including cli application) I can have GrpcInterceptor (sort of servlet filter in WEB world) that uses the same authentication provider for BearerTokenAuthenticationToken giving the end user the same programming model they used to with vanilla spring boot with familiar configuration properties and models.
Comment From: jvmlet
Not related to this feature request, but when I ran the application (not the test), the OnWebApplicationCondition was matched with 2.6.8.
Might be something related to processing of SpringBootTest annotation and it's default WebEnvironment.MOCK; seems it's not picked up by OnWebApplicationCondition
- I have
implementation 'org.springframework.boot:spring-boot-starter-web'as dependency
Comment From: jvmlet
I can confirm that SpringBootContextLoader of 2.6.6 loads GenericWebApplicationContext , but 2.6.8 - not.
GenericWebApplicationContext adds session scope that is being picked up and matched by OnWebApplicationCondition
private static class WebConfigurer {
void configure(MergedContextConfiguration configuration, SpringApplication application,
List<ApplicationContextInitializer<?>> initializers) {
WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration;
addMockServletContext(initializers, webConfiguration);
// BELOW LINE IS MISSING IN 2.6.8
application.setApplicationContextFactory((webApplicationType) -> new GenericWebApplicationContext());
}
Comment From: wilkinsona
@jvmlet You are setting the web application type to none in your tests. The fix for #29170 means that this configuration is now correctly honoured and your test is run with a non-web context.
Comment From: jvmlet
Thanks a lot @wilkinsona , indeed, my overlook.
Would you please also comment on original issue ? Having the ability to autoconfigure OAuth2ResourceServerAutoConfiguration without WEB environment opens doors for additional integration scenarious.
Thanks again for your support.
Comment From: wilkinsona
I'm not sure that it makes sense to me for OAuth2ResourceServerAutoConfiguration to be active in a non-web application. You use the example above of a CLI application and I struggle to think of such an application as a resource server. We'd also have to deal with quite a bit more complexity in deciding whether to autoconfigure a JwtDecoder or a ReactiveJwtDecoder. In short, this feels quite niche to me and I think it would be better handled in your own code where you can define a decoder that meets your needs.
Comment From: jvmlet
Another example from GRPC domain : I'm getting JWT token from grpc client and want to authenticate/authorize it against resource server. Without JwtAuthenticationProvider auto-configured I'm left with zero integration with spring-security.
Comment From: jvmlet
May be refactoring of JwtDecoderConfiguration into public class makes more sense ? It can be imported then from CustomAutoconfiguration
Comment From: philwebb
We've discussed this as a team and agree with @wilkinsona that this would be better handled directly in your own code. We'd rather keep JwtDecoderConfiguration package-private since it's intended exclusively for an OAuth2 resource server web application. Defining a decoder bean directly if you know how you will configure it shouldn't be much code.