Hi
I'm upgrading my app to Spring Boot 2.4.1 but have unfortunately hit a dependency issue.
I've downgraded the nimbus library to 7.1 as per other posts, but it seems that spring security itself is relying on a different version. There wasn't a ticket about this per-se and keen to see if there's an easy resolution whilst (#17808 or #17986 are being worked on). I wasn't sure that #17808 definitely fixes the problem - but is there a solution in the meantime?
Relevant parts from my pom files:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/>
</parent>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-active-directory-spring-boot-starter</artifactId>
<version>2.3.5</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot-starter</artifactId>
<version>2.3.5</version>
</dependency>
<!-- adding to ensure compatibility -->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>7.9</version>
</dependency>
The app now starts up (didn't without the downgrade to 7.9 nimbus) but it now fails on the authentication/authorisation process:
java.lang.NoSuchMethodError: 'void com.nimbusds.jose.proc.JWSVerificationKeySelector.<init>(java.util.Set, com.nimbusds.jose.jwk.source.JWKSource)'
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder$JwkSetUriJwtDecoderBuilder.jwsKeySelector(NimbusJwtDecoder.java:333)
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder$JwkSetUriJwtDecoderBuilder.processor(NimbusJwtDecoder.java:348)
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder$JwkSetUriJwtDecoderBuilder.build(NimbusJwtDecoder.java:361)
at org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory.buildDecoder(OidcIdTokenDecoderFactory.java:167)
at org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory.lambda$createDecoder$3(OidcIdTokenDecoderFactory.java:129)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705)
at org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory.createDecoder(OidcIdTokenDecoderFactory.java:128)
at org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory.createDecoder(OidcIdTokenDecoderFactory.java:66)
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.createOidcToken(OidcAuthorizationCodeAuthenticationProvider.java:235)
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:154)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:192)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:222)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.doFilterInternal(OAuth2AuthorizationRequestRedirectFilter.java:178)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:141)
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:829)
Hi, @chrisburrell , now the azure-spring-boot-starter
does not support spring-boot-2.4.x well, could you please use spring-boot2.3.5 for now?
After https://github.com/Azure/azure-sdk-for-java/pull/17808 merged, we will release a new GA version, then the problem will be fixed.
Next GA version will be released before the end of 2021.01.
@chenrujun as ticket which you mentioned is probably not valid (those versions are incompatible) do you have some workaround for now how to use spring-boot 2.4.x with azure spring boot (we are using currently azure-spring-boot-bom 2.3.5)?
@bilak , we just released 3.0.0
, please try this:
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-active-directory</artifactId>
<version>3.0.0</version>
</dependency>
3.0.0 is
still work for spring-boot 2.2 - 2.3.
We will release 3.2.0
for spring-boot 2.4.x before the end of this month, you can wait for the release.
Refs: https://repo.maven.apache.org/maven2/com/azure/spring/azure-spring-boot-starter-active-directory/
@chenrujun I've just write to this issue because It has in name general spring boot 2.4 and I want to upgrade to spring boot 2.4. It's shame that I can't, even when spring boot 2.4 is out for more than 2 months :-1:
And it's not only about active directory library.
@bilak
Sorry that we faced some problem when upgrade to spring boot 2.4.0.
Refs: https://github.com/Azure/azure-sdk-for-java/pull/17905
You can choose one of the options:
azure-spring-boot-starter-active-directory 3.0.0
, check whether it work well with spring-boot 2.4.azure-spring-boot-starter-xxx 3.2.0
in this month. which is work for spring-boot 2.4.Hi,
azure-spring-boot-starter-active-directory 3.0.0
does not work either...
You're my last step to have a production ready reactive have in prod :-)
Best regards,
Hi, @Tcharl .
You're my last step to have a production ready reactive have in prod :-)
Do you mean you are using Web on Reactive Stack? We do not support reactive for our starters now.
However, I succeed to use spring-boot-oauth2-client instead of azad dedicated library (what's the added value of the microsoft one?). App Insight sdk is the last problematic one...
@Tcharl
what's the added value of the microsoft one?
We support other functions like:
Refs:
+1 on this. Spring Boot 2.4.2 with Azure SDK results in the following classnotfound exception (oidc version used in Azure is too old):
2021-01-25, 07:30:36 ERROR java.lang.ClassNotFoundException: com.nimbusds.oauth2.sdk.http.CommonContentTypes
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at com.microsoft.aad.adal4j.AdalTokenRequest.toOAuthRequest(AdalTokenRequest.java:158)
at com.microsoft.aad.adal4j.AdalTokenRequest.executeOAuthRequestAndProcessResponse(AdalTokenRequest.java:86)
at com.microsoft.aad.adal4j.AuthenticationContext.acquireTokenCommon(AuthenticationContext.java:930)
at com.microsoft.aad.adal4j.AcquireTokenCallable.execute(AcquireTokenCallable.java:70)
at com.microsoft.aad.adal4j.AcquireTokenCallable.execute(AcquireTokenCallable.java:38)
at com.microsoft.aad.adal4j.AdalCallable.call(AdalCallable.java:47)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Please upgrade the following dependencies:
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>${oauth2-oidc-sdk.version}</version>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>${nimbus-jose-jwt.version}</version>
</dependency>
Got it working by using the following versions: (both spring oauth2 AND Azure SDK work in this case)
<microsoft-azure.version>1.38.1</microsoft-azure.version>
<nimbus-jose-jwt.version>9.4.1</nimbus-jose-jwt.version>
<oauth2-oidc-sdk.version>7.5</oauth2-oidc-sdk.version>
<spring.boot.version>2.4.2</spring.boot.version>
oauth2-oidc-sdk
greater or equal to 8.x
doesn't work.
Hope you guys will update this quickly as it's a dirty hack / difficult to maintain to have discrepancies in maven dependencies.
@jloisel .
We are working on it. Please wait for next release.
Refs: https://github.com/Azure/azure-sdk-for-java/blob/feature/core/reactorupgrade/eng/versioning/external_dependencies.txt#L224
Thanks! You can upgrade to Spring Boot 2.4.2
, Nimbus 9.4.1
and oidc 8.34.2
. Your "upgraded" dependencies are already out of date.
@jloisel
Thank you for your information.
Your "upgraded" dependencies are already out of date.
They are just patch version update. It's easy to us to update patch version.
@chenrujun any news with release compatible with spring boot 2.4.x?
@bilak
If everything goes well, we will release new version with compatible with spring-boot 2.4.x at the end of this month.
Here are more details:
reactor-core 3.4.3
is now available.
@jloisel
Thank you for your information.
This month's regular release have finished for some modules in this repo.
To keep the modules use the same version, reactor-core 3.4.x can be used from next month.
So we can not support spring-boot 2.4.x until next month's regular release.
Please wait.
Sorry for bring you trouble.
@chenrujun so we have next month, what is the status please? Are we going to wait next mont? :D
@bilak
Current plan is that we will release azure-spring-boot-starter-active-directory:3.3.0
before 2021-03-11, which will work with spring-boot:2.4.3
@chenrujun what about other libraries? azure-spring-boot-bom
mainly.
@bilak other libraries will be released, too. For spring-boot 2.4.
Hey @chenrujun, are you folks still on target for a March release or are we looking at mid-April now?
@raniemi , on March release.
Looks like 3.3.0 was released 🎉
https://mvnrepository.com/artifact/com.azure.spring/azure-spring-boot-starter-active-directory/3.3.0
Closing this issue because 3.3.0 is released, which support spring-boot:2.4.3.
This is not solved as other azure artifacts rely on adal4j:
https://mvnrepository.com/artifact/com.microsoft.azure/adal4j/1.6.6
Which in turn is still depending on an old version of oauth2-oidc-sdk
. There is still a dependency conflict if you try to use Azure client within a spring boot application.
@jloisel
Sorry I can't get your point.
Could you please check our sample project?
It does not depends on adal4j:
There is no conflict about oauth2-oidc-sdk:
Same to nimbus-jose-jwt:
Standalone Azure client still does depend on it:
https://mvnrepository.com/artifact/com.microsoft.azure/adal4j/1.6.4/usages?p=1
We're using Azure client:
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure</artifactId>
<version>1.40.0</version>
</dependency>
And it still transitively depends on adal4j, which in turn depends on old versions of oidc and nimbus.
A simple search shows there is still some code depending on adal4j in various locations:
https://github.com/Azure/azure-sdk-for-java/search?q=adal4j
I've spend some time trying to understand which dependency to use to start / stop vms on Azure, but it's really puzzling given how many artifacts there are. The migration guide doesn't explicit which dependencies to use either, it just contains some code.
EDIT: Found some samples:
https://github.com/Azure-Samples/compute-java-manage-vm/blob/master/src/main/java/com/azure/resourcemanager/compute/samples/ManageVirtualMachine.java
Seems like we need to use client 2.x.
Hi, @jloisel
Why are you using com.microsoft.azure:azure
? I mean what do you use it for?
I think you should use com.azure.resourcemanager:xxx.
Seems like we need to use client 2.x.
Do you mean now you want to use com.azure.resourcemanager:xxx
?
Hi,
We thought it was the right client to use, but we were wrong. I have migrated our codebase to use azure-resourcemanager-compute
along with azure-identity
.
We use Azure client to start / stop instances on Azure automatically based on our client needs.
We use Azure client to start / stop instances on Azure automatically based on our client needs.
Hi, @saragluna .
IMU,
azure
is track 1 library,
we should avoid using track 1 library.
Do we have track 2 library to start / stop instances on Azure?
@jloisel
We use Azure client to start / stop instances on Azure
Is the Azure client
you referred to the azure-resourcemanager-compute
library?
We used track 1 library until now. That's why we had issues with nimbus / oidc conflicts in Spring boot:
@Override
public AzureClient newClient(final AzureAccount account) {
final ApplicationTokenCredentials credentials = new ApplicationTokenCredentials(
account.getClientId(),
account.getTenantId(),
account.getClientSecret(),
ENVS.getOrDefault(account.getEnvironment(), AZURE));
final Authenticated auth = Azure.authenticate(credentials);
final Azure c = auth.withSubscription(account.getSubscriptionId());
return new ImmutableAzureClient(
c.disks(),
c.networks(),
c.virtualMachines(),
c.publicIPAddresses(),
c.networkInterfaces(),
c.galleries()
);
Now we use track 2 client:
@Override
public AzureClient newClient(final AzureAccount acc) {
final TokenCredential credential = new ClientSecretCredentialBuilder()
.clientId(acc.getClientId())
.clientSecret(acc.getClientSecret())
.tenantId(acc.getTenantId())
.build();
final AzureEnvironment env = ENVS.getOrDefault(acc.getEnvironment(), AZURE);
final AzureProfile profile = new AzureProfile(acc.getTenantId(), acc.getSubscriptionId(), env);
final ComputeManager compute = ComputeManager
.configure()
.withLogLevel(BASIC)
.authenticate(credential, profile);
final NetworkManager network = NetworkManager
.configure()
.withLogLevel(BASIC)
.authenticate(credential, profile);
return new ImmutableAzureClient(
compute.disks(),
network.networks(),
compute.virtualMachines(),
network.publicIpAddresses(),
network.networkInterfaces(),
compute.galleries()
);
We switched from using azure
artifact to azure-resourcemanager-compute
library.
@jloisel
After you use track 2 library, do you have any problem?
It's working fine now. :+1:
Most helpful comment
reactor-core
3.4.3
is now available.