Skip to content

Apply JWT decoder timeout properties for AAD and B2C resource servers#49329

Merged
rujche merged 5 commits into
mainfrom
rujche/main/add-timeout-for-JwtDecoder
Jun 2, 2026
Merged

Apply JWT decoder timeout properties for AAD and B2C resource servers#49329
rujche merged 5 commits into
mainfrom
rujche/main/add-timeout-for-JwtDecoder

Conversation

@rujche
Copy link
Copy Markdown
Member

@rujche rujche commented Jun 1, 2026

Description

  • Apply jwtConnectTimeout/jwtReadTimeout properties to RestTemplate used by JWT decoder in AadResourceServerConfiguration and AadB2cResourceServerAutoConfiguration
  • Remove incorrect @deprecated annotation from timeout properties in AadAuthenticationProperties and AadB2cProperties (the deprecation was based on a RestOperations bean mechanism from PR [FEATURE REQ] Connecting to Azure-AD via proxy #26493 #30456 that was later removed, making the deprecation guidance invalid)
  • Fix javadoc: correct default value description from '500s' to '500ms'
  • Add tests for default and custom timeout property values

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

- Apply jwtConnectTimeout/jwtReadTimeout properties to RestTemplate used
  by JWT decoder in AadResourceServerConfiguration and
  AadB2cResourceServerAutoConfiguration
- Remove incorrect @deprecated annotation from timeout properties in
  AadAuthenticationProperties and AadB2cProperties (the deprecation was
  based on a RestOperations bean mechanism from PR #30456 that was later
  removed, making the deprecation guidance invalid)
- Fix javadoc: correct default value description from '500s' to '500ms'
- Add tests for default and custom timeout property values
Copilot AI review requested due to automatic review settings June 1, 2026 06:23
@rujche rujche requested review from a team, Netyyyy, moarychan and saragluna as code owners June 1, 2026 06:23
@github-actions github-actions Bot added the azure-spring All azure-spring related issues label Jun 1, 2026
@rujche rujche self-assigned this Jun 1, 2026
@rujche rujche moved this from Todo to In Progress in Spring Cloud Azure Jun 1, 2026
@rujche rujche added this to the 2026-06 milestone Jun 1, 2026
@rujche rujche added azure-spring-aad Spring active directory related issues. azure-spring-aad-b2c Spring active directory b2c related issues. bug This issue requires a change to an existing behavior in the product in order to be resolved. labels Jun 1, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Spring Cloud Azure (autoconfigure) resource-server support so the jwtConnectTimeout / jwtReadTimeout properties are actually applied to the HTTP client used for JWK retrieval, and cleans up related property metadata and tests.

Changes:

  • Apply configured JWT connect/read timeouts to the RestTemplate/RestTemplateBuilder used by AAD and B2C JWT decoding/JWK retrieval.
  • Remove incorrect @Deprecated markers on JWT timeout/size-limit properties and fix the documented default timeout unit.
  • Add unit tests for default/custom timeout property binding.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 24 comments.

Show a summary per file
File Description
sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aadb2c/configuration/AadB2cResourceServerAutoConfiguration.java Applies B2C timeout properties to the RestTemplateBuilder used for JWK retrieval.
sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfiguration.java Applies AAD timeout properties to the RestTemplate passed into NimbusJwtDecoder.
sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aadb2c/configuration/properties/AadB2cProperties.java Removes deprecations and updates Javadoc defaults for JWT timeout/size-limit properties.
sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/properties/AadAuthenticationProperties.java Removes deprecations and updates Javadoc defaults for JWT timeout/size-limit properties.
sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aadb2c/configuration/AadB2cResourceServerAutoConfigurationTests.java Adds tests for default/custom B2C timeout property values.
sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/configuration/AadResourceServerConfigurationTests.java Adds tests for default/custom AAD timeout property values.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@rujche
Copy link
Copy Markdown
Member Author

rujche commented Jun 1, 2026

/azp run java - spring - tests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@abjugard
Copy link
Copy Markdown

abjugard commented Jun 1, 2026

What's a rough timeframe for this to make it to a release of com.azure.spring spring-cloud-azure-dependencies?

@rujche
Copy link
Copy Markdown
Member Author

rujche commented Jun 2, 2026

@abjugard

What's a rough timeframe for this to make it to a release of com.azure.spring spring-cloud-azure-dependencies?

Current plan is releasing it before the end of June.

Copy link
Copy Markdown
Member

@Netyyyy Netyyyy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@rujche rujche merged commit b196db5 into main Jun 2, 2026
84 checks passed
@rujche rujche deleted the rujche/main/add-timeout-for-JwtDecoder branch June 2, 2026 01:47
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Spring Cloud Azure Jun 2, 2026
@abjugard
Copy link
Copy Markdown

abjugard commented Jun 2, 2026

@rujche I found this ticket which was closed without resolution: #42159 which made me look deeper into this.

Both before and after this PR, I am not sure that the code that sets up the cache was correctly adapted to upstream changes in Nimbus, it appears to me that the relevant keys for configuring the cache (spring.cloud.azure.active-directory.jwk-set-cache-lifespan and .jwk-set-cache-refresh-time) are only read by a JWKSetCache Bean, which is something RemoteJWKSet uses, but RemoteJWKSet is not being used when the NimbusJwtDecoder is built, that is done by calling NimbusJwtDecoder.withJwkSetUri at

NimbusJwtDecoder nimbusJwtDecoder = NimbusJwtDecoder
.withJwkSetUri(identityEndpoints.getJwkSetEndpoint())
.restOperations(createRestTemplate(restTemplateBuilder
.connectTimeout(aadAuthenticationProperties.getJwtConnectTimeout())
.readTimeout(aadAuthenticationProperties.getJwtReadTimeout())))
.build();

It seems to me that we would have to call .cache before line 63 (.build()) there or do something like:

JWKSource<SecurityContext> jwkSource = JWKSourceBuilder
        .create(URI.create(identityEndpoints.getJwkSetEndpoint()).toURL())
        .cache(aadProps.getJwkSetCacheLifespan().toMillis(), aadProps.getJwtConnectTimeout().toMillis())
        .refreshAheadCache(aadProps.getJwkSetCacheRefreshTime().toMillis(), true)
        .build();

NimbusJwtDecoder nimbusJwtDecoder = NimbusJwtDecoder
        .withJwkSource(jwkSource)
        .build();

in order to wire the NimbusJwtDecoder with cache.

If you want me to I can open a separate ticket for this?

@rujche
Copy link
Copy Markdown
Member Author

rujche commented Jun 3, 2026

Hi, @abjugard . Thanks for the comment. I opened this issue (#42159) and created a new PR (#49356), please help to review when you are available.

@abjugard
Copy link
Copy Markdown

abjugard commented Jun 3, 2026

@rujche Looks good to me as a fix for the unused cache bug.

Improvement suggestion: enable the use of a Bean-injected customizer for the JWKSourceBuilder using the customizer pattern, allowing users to supply their own advanced configurations.

Here's an example of how this looks with Jackson, this customizer bean is then used whenever a JsonMapper is constructed:

@Configuration
class JacksonConfig {

    @Bean
    JsonMapperBuilderCustomizer jacksonCustomizer() {
        return builder -> builder
                .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
                .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
                .disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES)
                .disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)
                .changeDefaultPropertyInclusion(inclusion ->
                        inclusion.withValueInclusion(JsonInclude.Include.NON_NULL));
    }
}

Alternatively look at the non-deprecated mechanisms for setting up the JWK source in nimbus, there are a number of nice to have features supported there, e.g. .outageTolerant, .retrying, along with background fetching, which all serve to improve the resilience of the components that rely on this, which are currently out of users reach when using the auto-configuration provided here, meaning they would have to configure JWK source manually in order to use them. The alternative to the customizer suggestion would be to expose individual properties for each of these.

@rujche
Copy link
Copy Markdown
Member Author

rujche commented Jun 4, 2026

Hi, @abjugard . Thanks for the review and suggestion.

Improvement suggestion: enable the use of a Bean-injected customizer for the JWKSourceBuilder using the customizer pattern, allowing users to supply their own advanced configurations.

In this PR (#49356), ,JWKSourceBuilder is not used to create a bean, do you mean customizer for JwtDecoder?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

azure-spring All azure-spring related issues azure-spring-aad Spring active directory related issues. azure-spring-aad-b2c Spring active directory b2c related issues. bug This issue requires a change to an existing behavior in the product in order to be resolved.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants