Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/spring/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This section includes changes in `spring-cloud-azure-autoconfigure` module.

#### Bugs Fixed

- Fixed Service Bus JMS listener containers using `JmsPoolConnectionFactory` when both `spring.jms.servicebus.pool.enabled=true` and `spring.jms.cache.enabled=false`. The sender continues to use `JmsPoolConnectionFactory`, while listener containers now use a dedicated `ServiceBusJmsConnectionFactory`, enabling topic subscriptions on the Standard tier. ([#49308](https://github.com/Azure/azure-sdk-for-java/issues/49308))
- Fixed the AAD authentication filter (`AadAuthenticationFilter` and `AadAppRoleStatelessAuthenticationFilter`) not validating the `tid` (tenant ID) claim in JWT tokens against the configured tenant, allowing tokens from other tenants to be accepted. The JWT token validator now validates that the token's `tid` claim matches the configured tenant ID, preventing cross-tenant authentication bypass. This hardening is only enforced when a specific tenant ID is configured. ([#49631](https://github.com/Azure/azure-sdk-for-java/pull/49631))
- Fixed the AAD and B2C OpenID Connect login (`oauth2Login`) ID token decoders not validating the `iss` (issuer) and `aud` (audience) claims. `AadOidcIdTokenDecoderFactory` and `AadB2cOidcIdTokenDecoderFactory` now validate the standard OIDC ID token claims (audience, expiry, issued-at and subject) and the issuer. For single tenant applications the issuer must belong to the configured tenant, and for multi-tenant applications (the `common`, `organizations` or `consumers` endpoints) the issuer must be a trusted Microsoft identity platform issuer consistent with the token's own `tid` claim. This prevents users from unauthorized tenants from signing in to multi-tenant applications that rely on the issuer/tenant claim for tenant restriction ([#49423](https://github.com/Azure/azure-sdk-for-java/pull/49423)).
- Fixed the missing bean name in `@ConditionalOnMissingBean` for `LettuceClientConfigurationBuilderCustomizer` ([#49290](https://github.com/Azure/azure-sdk-for-java/issues/49290)).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class ServiceBusJmsContainerConfiguration implements DisposableBean {
* <tr><td>not set</td><td>false</td><td>ServiceBusJmsConnectionFactory</td></tr>
* <tr><td>true</td><td>not set</td><td>JmsPoolConnectionFactory</td></tr>
* <tr><td>true</td><td>true</td><td>CachingConnectionFactory</td></tr>
* <tr><td>true</td><td>false</td><td>JmsPoolConnectionFactory</td></tr>
* <tr><td>true</td><td>false</td><td>ServiceBusJmsConnectionFactory</td></tr>
* <tr><td>false</td><td>not set</td><td>ServiceBusJmsConnectionFactory</td></tr>
* <tr><td>false</td><td>true</td><td>CachingConnectionFactory</td></tr>
* <tr><td>false</td><td>false</td><td>ServiceBusJmsConnectionFactory</td></tr>
Expand All @@ -62,7 +62,7 @@ class ServiceBusJmsContainerConfiguration implements DisposableBean {
// pool: not set
{SERVICE_BUS, CACHE, SERVICE_BUS}, // cache: not set, true, false
// pool: true
{POOL, CACHE, POOL}, // cache: not set, true, false
{POOL, CACHE, SERVICE_BUS}, // cache: not set, true, false
// pool: false
{SERVICE_BUS, CACHE, SERVICE_BUS} // cache: not set, true, false
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,39 @@ void listenerContainerUsesPoolConnectionFactoryWhenExplicitlyEnabled(String pric
});
}

@ParameterizedTest
@ValueSource(strings = {"standard", "premium"})
void listenerContainerUsesDedicatedServiceBusConnectionFactoryWhenPoolEnabledAndCacheDisabled(String pricingTier) {
this.contextRunner
.withPropertyValues(
"spring.jms.servicebus.pricing-tier=" + pricingTier,
"spring.jms.servicebus.connection-string=" + CONNECTION_STRING,
"spring.jms.servicebus.pool.enabled=true",
"spring.jms.cache.enabled=false"
)
.run(context -> {
JmsPoolConnectionFactory senderBean = context.getBean(JmsPoolConnectionFactory.class);
Object pooledTarget = senderBean.getConnectionFactory();
DefaultJmsListenerContainerFactory queueFactory = context.getBean(
"jmsListenerContainerFactory", DefaultJmsListenerContainerFactory.class);
DefaultJmsListenerContainerFactory topicFactory = context.getBean(
"topicJmsListenerContainerFactory", DefaultJmsListenerContainerFactory.class);

DefaultMessageListenerContainer queueContainer =
queueFactory.createListenerContainer(mock(JmsListenerEndpoint.class));
DefaultMessageListenerContainer topicContainer =
topicFactory.createListenerContainer(mock(JmsListenerEndpoint.class));

assertThat(queueContainer.getConnectionFactory())
.isInstanceOf(ServiceBusJmsConnectionFactory.class)
.isNotSameAs(pooledTarget);
assertThat(topicContainer.getConnectionFactory())
.isInstanceOf(ServiceBusJmsConnectionFactory.class)
.isNotSameAs(pooledTarget)
.isSameAs(queueContainer.getConnectionFactory());
});
}

@ParameterizedTest
@ValueSource(strings = {"standard", "premium"})
void listenerContainerUsesDedicatedServiceBusConnectionFactoryWhenPoolDisabled(String pricingTier) {
Expand Down