spring-security icon indicating copy to clipboard operation
spring-security copied to clipboard

Add support dpop customization

Open franticticktick opened this issue 8 months ago • 12 comments

Currently dpop can't be configured. OAuth2ResourceServerConfigurer has dPoPAuthenticationConfigurer and it is already initialized with DPoPAuthenticationConfigurer and in configure method it is always applied to http. It would be nice to separate dpop configuration instead of applying it by default. For example:

		@Bean
		SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
			// @formatter:off
			http
				.authorizeHttpRequests((authorize) ->
					authorize.anyRequest().authenticated()
				)
				.oauth2ResourceServer((oauth2ResourceServer) ->
					oauth2ResourceServer
						.jwt(Customizer.withDefaults())
						.dpop(Customizer.withDefaults())
				);
			// @formatter:on
			return http.build();
		}

franticticktick avatar Apr 15 '25 11:04 franticticktick

@franticticktick Can you provide some specific use cases on what you need to customize for a DPoP flow?

jgrandja avatar Apr 15 '25 13:04 jgrandja

@jgrandja Firstly, it would be nice if dpop was optional, now it is always enabled. Secondly, the same Authorization header is specified everywhere, it is standard, but it can be different, which is a normal situation. That is, at least I want to be able to customize authenticationConverter and requestMatcher. In addition, I may need additional audit of successful authentication and I need a custom AuthenticationSuccessHandler.

franticticktick avatar Apr 15 '25 14:04 franticticktick

@jgrandja I can prepare a PR if this ticket is relevant.

franticticktick avatar Apr 15 '25 15:04 franticticktick

Thank you @franticticktick. I've assigned it to you.

No rush as this is scheduled for 7.0.x.

jgrandja avatar Apr 15 '25 15:04 jgrandja

Hi @franticticktick & @jgrandja,

while trying out spring-boot 3.5.0 (which includes spring-security 6.5.0) we noticed that our setup does not work anymore due to the auto init of DPoP.

We are using the oauth 2.0 resource server with an OpaqueTokenIntrospector and not JWT, therefore we do not have spring-security-oauth2-jose as a dependency and the classes are not on the class path during runtime.

A ClassNotFoundException (org.springframework.security.oauth2.jwt.JwtException) is thrown during start-up while configuring DPoP.

In the end there are three possible solutions for us:

  • we just include spring-security-oauth2-jose as a dependency. however, this would be temporary mitigation
  • DPoP is only configured in case of JWT being enabled / spring-security-oauth2-jose on the class path
  • there is an option to disable DPoP

Due to the third option I figured this could be part of this issue and I opted to comment first instead of creating a separate issue.

Please let me know if you think this should be a separate issue, or if I can support in any way here.

pheyken avatar May 23 '25 06:05 pheyken

Hi @pheyken Indeed, such a problem exists. But it seems to me that this is a rather rare case. If you have a stable working solution, then it would be good if you wait until we finish working on this ticket. If this problem is still widespread, then we can consider the possibility of disabling dpop.

franticticktick avatar May 23 '25 12:05 franticticktick

@pheyken As you already noticed, DPoP is enabled by default and it does require the spring-security-oauth2-jose dependency. There is no way to disable DPoP so as a temporary workaround you need to include spring-security-oauth2-jose dependency. This ticket will address the 3rd option:

there is an option to disable DPoP

jgrandja avatar May 26 '25 15:05 jgrandja

@pheyken Please see comment

jgrandja avatar Jun 16 '25 16:06 jgrandja

Please consider adding:

  • jti validator customization (DPoPProofJwtDecoderFactory.setJwtValidatorFactory()) to replace default local JTI_CACHE with some distributed/shared cache. This will help multiple OAuth2 resource server share a common jti cache to prevent replay attacks (see https://datatracker.ietf.org/doc/html/rfc9449#Token_Replay)
  • an option to enforce consuming only DPoP 'sender-constrained' access tokens (if normal 'bearer' access token is submitted, it will be rejected)
  • dpop specific metadata (eg: dpop_bound_access_tokens_required and dpop_signing_alg_values_supported) in OAuth2ProtectedResourceMetadata (see https://datatracker.ietf.org/doc/html/rfc9728/#name-protected-resource-metadata)
  • support for Server-Provided Nonce (see https://datatracker.ietf.org/doc/html/rfc9449#RSNonce)

ferrerogg avatar Nov 11 '25 13:11 ferrerogg

Thanks for the additional info @ferrerogg. Some of those items will likely be added into a new issue. Let's leave it here for now.

@franticticktick Let's work on merging what you have in gh-17202 before we look at addressing any of these items.

jgrandja avatar Nov 12 '25 11:11 jgrandja

@jgrandja please see my comment in regards to reverse proxy in https://github.com/spring-projects/spring-security/pull/17202#issuecomment-3570421915.

renannprado avatar Nov 24 '25 11:11 renannprado