Skip to content

[FEATURE REQ] Authentication in Spring enhancement #32443

Description

@stliu

How TokenCredential is supported in Spring Cloud Azure

This doc discusses how TokenCredential is managed within Spring Cloud Azure and expected behaviors for each scenarios

Scenario 1

spring.cloud.azure:
  storage-blob:
    endpoint:
  eventhub:
    endpoint:

This is the most common scenario I think.

Expectation:

  • There should be One TokenCredntial bean in Spring Context
    • This bean is used by both BlobClient and EventHubClient
    • The bean type should be a ChainedTokenCredential and has the same elements as DAC

Current Behavior:

  • There is One TokenCredential bean in Spring Context
    • This bean is used by both BlobClient and EventHubClient
    • The bean type is ChainedTokenCredential and has the same elements as DAC.
  • There is One ChainedTokenCredential instance created at the JVM start-up.

Scenario 2

spring.cloud.azure:
  credential:
    client-id:
    client-secret:	
  storage-blob:
    endpoint:
  eventhub:
    endpoint:

in this case, it should be

Expectation:

  • One ServicePrincipalCredential bean in Spring Context from spring.cloud.azure.credential
    • This bean is used by BlobClient and EventHubClient

Current Behavior:

  • There is One ServicePrincipalCredential bean in Spring Context from spring.cloud.azure.credential
  • There are Three TokenCredenital instances created by Spring Cloud Azure:
    • One ChainedTokenCredential instance created at the JVM start-up.
    • Two ServicePrincipalCredential instances created from spring.cloud.azure.storage-blob.credential and spring.cloud.azure.eventhub.credential.
      • The one ServicePrincipalCredential instance created from spring.cloud.azure.storage-blob.credential is used by BlobClient
      • The one ServicePrincipalCredential instance created from spring.cloud.azure.eventhub.credential is used by EventHubClient

Scenario 3

spring.cloud.azure:
  storage-blob:
    endpoint:
  eventhub:
    endpoint:
@Configuration
UserCustommizeConfiguration{
  @Bean(name="springCloudAzureDefaultCredential")
  TokenCredential tokenCredential() {
  }	
}

In this case, it should be

Expectation:

  • One TokenCredential bean in Spring Context, which is the user-provided one
    • It is used by BlobClient and EventHubClient
  • Spring Cloud Azure should NOT create any TokenCredential instances nor bean

Current Behavior:

  • There is One TokeCredential bean in Spring Context, the user provided one.
    • It is used by both BlobClient and EventHubClient.
  • There is One ChainedTokenCredential instance created at the JVM start-up.
  • Spring Cloud Azure doesn't create any TokenCredential bean

Scenario 4

spring.cloud.azure:
  storage-blob:
    endpoint:
    credential:
      client-id:
      client-secret:
  eventhub:
    endpoint:
@Configuration
UserCustommizeConfiguration{
    @Bean(name="springCloudAzureDefaultCredential")
    TokenCredential tokenCredential() {
    }
}

Unlike scenario 3, the User in this scenario provides a TokenCredential bean and has credential configuration provided in application properties for the Storage Blob service.

Expectation:

  • In this case, there will be One TokenCredential bean
    • The one is provided by customer configuration code, which will be used to authenticate EventHubClient
  • In this case, there will be One TokenCredential instance
    • It is created Spring Cloud Azure from spring.cloud.azure.storage-blob.credential config, which is a ServicePrincipalTokenCredential

Current Behavior:

  • There are One TokenCredential bean
    • One is provided by the customer to authenticate EventHubClient
  • There is Two TokenCredential instances
    • One is ChainedTokenCredential instance created at the JVM start-up.
    • Another one is created by Spring Cloud Azure from spring.cloud.azure.storage-blob.credential config, which is a ServicePrincipalTokenCredential
      • This one is used by the StorageBlobClient

Scenario 5

spring.cloud.azure:
  storage-blob:
    endpoint:
  eventhub:
    endpoint:
@Configuration
UserCustommizeConfiguration{
  @Bean
  TokenCredential tokenCredential() {
  }	
}

In this case, it should be

Expectation:

  • TBD

Current Behavior:

  • There are Two TokeCredential beans in Spring Context,
    • One TokeCredential bean as scenario#1 created by Spring Cloud Azure. It is used by both BlobClient and EventHubClient.
    • Another one is the user-provided bean, which is not used by any Spring Cloud Azure code.
  • There is One ChainedTokenCredential instance created at the JVM start-up.

Scenario 6

spring.cloud.azure:
  storage-blob:
    endpoint:
    credential:
      client-id:
      client-secret:
  eventhub:
    endpoint:

Expectation:

  • In this case, there will be One TokenCredential bean
    • The one is one is created by Spring Cloud Azure internally, which is a ChainedTokenCredential as same as scenario 1, that will be used to authenticate EventHubClient
  • In this case, there will be One TokenCredential instance
    • It is created Spring Cloud Azure from spring.cloud.azure.storage-blob.credential config, which is a ServicePrincipalTokenCredential

Current Behavior:

  • There is One TokenCredential bean
    • This bean is used by EventHubClient
    • The bean type is ChainedTokenCredential and has the same elements as DAC.
  • There are Two TokenCredential instances created at the JVM start-up.
    • One is ChainedTokenCredential instance created at the JVM start-up.
    • Another one is created by Spring Cloud Azure from spring.cloud.azure.storage-blob.credential config, which is a ServicePrincipalTokenCredential
      • This one is used by the StorageBlobClient

Scenario 7

spring.cloud.azure:
  storage-blob:
    endpoint:
    credential:
      client-id:
      client-secret:
  eventhub:
    endpoint:
  keyvault:
    secret:
      endpoint:
      property-source-enabled: true

This scenario consists of:

  1. 3 azure services are used in the application
    • Storage Blob
    • Event Hubs
    • KeyVault Secrets
  2. Property source is enabled for the KeyVault Service, which means that the SecretClient must be ready (authenticated) in Bootstrap stage.
  3. Storage Blob has its own credential configured

Expectation:

about TokenCredential:

  • There is One TokenCredential bean
    • One ChainedTokenCredential bean, as described in scenario 1, is created at BootstrapContext stage, so it is used by SecretClient in EnvironmentPostProcessor and EventHubClient
  • There is One TokenCredential instance
    • One ServicePrincipalTokenCredential is created by Spring Cloud Azure from spring.cloud.azure.storage-blob.credential properties
      • This ServicePrincipalTokenCredential is used to authenticate StorageBlobClient and created at building Application Context Stage.

Current Behavior:

  • There is One TokenCredential bean
    • One ChainedTokenCredential bean is created at the application context stage, and it is used by EventHubClient.
  • There are Two TokenCredential instances
    • One is ChainedTokenCredential instance created at the JVM start-up
      • This one is used by the Key Vault property source
    • One ServicePrincipalTokenCredential is created by Spring Cloud Azure from spring.cloud.azure.storage-blob.credential properties
      • This ServicePrincipalTokenCredential is used to authenticate StorageBlobClient and created at the building Application Context Stage.

Scenario 8

spring.cloud.azure:
  storage-blob:
    endpoint:
    credential:
      client-id:
      client-secret:
  eventhub:
    endpoint:
  keyvault:
    secret:
      endpoint:
      property-source-enabled: true
InstanceSupplier<TokenCredential> tokenCredentialSupplier = ctx -> new AZDTokenCredential();
SpringApplication application = new SpringApplication(MyApplication.class);
application.addBootstrapper(registry -> registry.register(TokenCredential.class, tokenCredentialSupplier));

Like scenario 7, the only difference is that user is trying to provide its own TokenCredential bean to be used by both SecretClient and EventHubClient.

Expectation:

Since this application has property source feature, it can not use the normal Configuration to define the bean, but has to do it in the bootstrap stage, see more detials at [here](https://docs.spring.io/spring-cloud-vault/docs/current/reference/html/#vault.configdata.customization)

  • There is One TokenCredential bean
    • It is provided by user from the code, is used by SecretClient in EnvironmentPostProcessor and EventHubClient
  • There is One TokenCredential instance
    • One ServicePrincipalTokenCredential is created by Spring Cloud Azure from spring.cloud.azure.storage-blob.credential properties
    • This ServicePrincipalTokenCredential is used to authenticate StorageBlobClient and created at building Application Context Stage.

Current Behavior:

  • Won't use the TokenCredential defined in BootstrapContext
  • There is One TokenCredential bean
    • One ChainedTokenCredential bean is created at the application context stage, and it is used by EventHubClient.
  • There are Two TokenCredential instances
    • One is ChainedTokenCredential instance created at the JVM start-up
      • This one is used by the Key Vault property source
    • One ServicePrincipalTokenCredential is created by Spring Cloud Azure from spring.cloud.azure.storage-blob.credential properties
      • This ServicePrincipalTokenCredential is used to authenticate StorageBlobClient and created at the building Application Context Stage.

Scenario 9

spring.cloud.azure:
  storage-blob:
    credential:
      client-id:
  eventhub:
    endpoint:

If users create a DAC and set the client id:

TokenCredential credential = new DefaultAzureCredentialBuilder().managedIdentityClientId("some-client-id").build();

This credential can be used in the Azure Hosting environment and on local machines.

So this scenario is, what if storage blob wants to use a different DAC as we provide in scenario 1?

Expectation

  • There is One TokenCredential bean
    • One ChainedTokenCredential bean, as described in scenario 1, and it is used by the EventHubClient
  • There is One ChainedTokenCredential instance
    • One ChainedTokenCredential instance, created from spring.cloud.azure.storage-blob.credential
      • This one is used by the StorageBlobClient

Current Behavior

  • There is One TokenCredential bean
    • One ChainedTokenCredential bean, as described in scenario 1, and it is used by the EventHubClient
  • There is One ChainedTokenCredential instance
    • No ChainedTokenCredential instance created from spring.cloud.azure.storage-blob.credential
    • One is ChainedTokenCredential instance created at the JVM start-up
      • This one is used by the StorageBlobClient

Metadata

Metadata

Assignees

Labels

ClientThis issue points to a problem in the data-plane of the library.azure-springAll azure-spring related issuesfeature-requestThis issue requires a new behavior in the product in order be resolved.

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions