Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bridge azure properties to spring starter to authenticate #5

Conversation

moarychan
Copy link

@moarychan moarychan commented Jul 23, 2021

Fixes Azure#21971

Based on the target PR changes, try to use each starter property class and the super AzureProperties to construct TokenCredential to authenticate.

Changelog;

  • Add a new ChainedTokenCredential bean, then it will be used as the final token credential to each service client builder.

    • The first is each module's TokenCredential, it's created by SpringMappingCredentialPropertiesProvider.
      MappingCredentialPropertiesProvider.java interface to mapping each module properties to
      MappingCredentialPropertiesProvider implementation, then rach module will use SpringEnvironmentCredentialBuilder
      object to build a starter's TokenCredential which will be used as a credential option.
      Provider DefaultQueueClientBuilderCustomizer to cover the common use-cases, and combine the
    • The second is the Azure Spring's common TokenCredential, it's created from AzureDefaultTokenCredentialAutoConfiguration auto-configuration.
  • Use Configurer and Customizer pattern to apply each module service client builder definition.
    The abstract class AbstractClientBuilderConfigurer to customize the special configured.

    Below interfaces are credential customizer:

    • AzureKeyCredentialClientBuilderCustomizer
    • ConnectionStringClientBuilderCustomizer
    • SharedKeyCredentialClientBuilderCustomizer
    • TokenCredentialClientBuilderCustomizer

Todolist:

  • Properties validation if not configured any credential information.
  • Cosmos
  • Storage Blob
  • Storage Queue
  • [WIP] KeyVault
  • EventHubs
  • Service Bus
  • Update and add Unit testcases
  • Test with all related samples
  • Update dev docs

@saragluna saragluna self-requested a review July 23, 2021 06:27
@saragluna saragluna self-assigned this Jul 23, 2021

@Override
public void mapAzureProperties(
CredentialProperties credentialProperties,
Copy link
Owner

Choose a reason for hiding this comment

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

Personally I don't like this code style.

@@ -44,20 +46,44 @@ protected String getDatabaseName() {
}

@Bean
@ConditionalOnMissingBean
Copy link
Owner

Choose a reason for hiding this comment

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

Do we really need this to be a bean?

Copy link
Owner

Choose a reason for hiding this comment

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

I mean the source of this key could only be the CosmosProperties.

Copy link
Owner

Choose a reason for hiding this comment

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

For @saragluna, we need to check the key rotation logic here.

public BlobServiceClientBuilder blobServiceClientBuilder(
StorageProperties storageProperties,
ObjectProvider<MappingCredentialPropertiesProvider> mappingPropertiesProviders,
ObjectProvider<TokenCredential> defaultTokenCredentials) {
Copy link
Owner

Choose a reason for hiding this comment

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

why is this called defaultTokenCredentials? Will there be multiple default token crdentials?

@@ -0,0 +1,4 @@
package com.azure.spring.autoconfigure.unity;

public interface SpringAzureProperties {
Copy link
Owner

Choose a reason for hiding this comment

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

Why this empty interface?

Copy link
Owner

Choose a reason for hiding this comment

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

Per discussion, maybe we could remove this now.

@@ -24,6 +28,7 @@
* Auto-configuration for Azure Spring default token credential.
*/
@Configuration
@ConditionalOnProperty(name = AzureProperties.PREFIX)
Copy link
Owner

Choose a reason for hiding this comment

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

Do we really need to depend on this property bean?

Copy link
Author

Choose a reason for hiding this comment

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

No, I will remove it

@@ -87,6 +92,12 @@ public TokenCredential azureTokenCredential(List<SpringCredentialBuilderBase> cr
return chainedTokenCredentialBuilder.build();
}

@Bean
public MappingCredentialPropertiesProvider cosmosCredentialPropertiesProvider(
Copy link
Owner

Choose a reason for hiding this comment

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

What if service bus and cosmos work together?

return cosmosClientBuilder.credential(azureKeyCredential);
}

MappingCredentialPropertiesProvider propertiesProvider = mappingPropertiesProviders.orderedStream()
Copy link
Owner

Choose a reason for hiding this comment

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

How about using this EnvironemtCredential and the Azure Default Token Credential to construct a chained token credential?

@@ -20,7 +21,7 @@
*/
@Validated
@ConfigurationProperties(CosmosProperties.PREFIX)
public class CosmosProperties extends AzureProperties {
public class CosmosProperties extends AzureProperties implements SpringAzureProperties {
Copy link
Owner

Choose a reason for hiding this comment

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

No need of SpringAzureProperties.

import javax.validation.constraints.Pattern;

/**
* @author Warren Zhu
*/
@Validated
@ConfigurationProperties("spring.cloud.azure.storage")
public class AzureStorageProperties {
public class AzureStorageProperties extends AzureProperties implements SpringAzureProperties {
Copy link
Owner

Choose a reason for hiding this comment

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

No need to implement SpringAzureProperties.

StorageAccountManager storageAccountManager) {

final String accountName = storageProperties.getAccount();
public QueueClientBuilderConfigurer queueClientBuilderConfigurer(
Copy link
Owner

Choose a reason for hiding this comment

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

Do we need each new type of configurer for each sdk builder?

Copy link
Owner

Choose a reason for hiding this comment

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

interface AzureKeyCredentialBuilderCustomizer {
	keyCredential();
}

interface AzureNamedKeyCredentialBuilderCustomizer {
	namedKeyCredential;
}

interface AzureSdkClientBuilderCustomizer {
	
	tokenCredential();

	httpClient();
}	


class KVBuilderCustomizer implements AzureKeyCredentialBuilderCustomizer,
									 AzureSdkClientBuilderCustomizer,
									 AzureNamedKeyCredentialBuilderCustomizer {
	
	tokenCredential();

	keyCredntial();

	httpClient();

	configure() {

	}
}

class SBBuilderCustomizer implements AzureKeyCredentialBuilderCustomizer,
									 AzureSdkClientBuilderCustomizer,
									 AzureNamedKeyCredentialBuilderCustomizer {
	
	tokenCredential();

	keyCredntial();

	httpClient();

	configure() {

	}
}

}

@Bean(COSMOS_CHAINED_TOKEN_CREDENTIAL_BEAN_NAME)
@ConditionalOnMissingBean
Copy link
Owner

Choose a reason for hiding this comment

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

Will @ConditionalOnMissingBean check the bean name?


@Bean(COSMOS_CHAINED_TOKEN_CREDENTIAL_BEAN_NAME)
@ConditionalOnMissingBean
public ChainedTokenCredential cosmosChainedTokenCredential(TokenCredential defaultTokenCredential) {
Copy link
Owner

Choose a reason for hiding this comment

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

This TokenCredential could accidentally pick up the TokenCredential defined in other auto-configuration classes.

public AzureKeyCredential azureKeyCredential() {
return new AzureKeyCredential(cosmosProperties.getKey());
@ConditionalOnMissingBean
public ClientBuilderCustomizer<CosmosClientBuilder> cosmosClientBuilderCustomizers() {
Copy link
Owner

Choose a reason for hiding this comment

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

How about putting this into the builder creation method?

@Override
public CosmosClientBuilder configure(CosmosClientBuilder builder) {
configureClientBuilder(builder);
if (azureKeyCredentialCustomizer != null) {
Copy link
Owner

Choose a reason for hiding this comment

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

How about omitting the DefaultSkipCredentialCallback and setting the credential by precedence, first setting the lower precedence and higher precedence.

return Optional.ofNullable(properties.getKey())
.filter(StringUtils::hasText)
.map(AzureKeyCredential::new)
.orElse(null);
Copy link

Choose a reason for hiding this comment

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

null?

if (cosmosAzureKeyCredential != null) {
return builder -> builder.credential(cosmosAzureKeyCredential);
}
return null;
Copy link

Choose a reason for hiding this comment

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

we should discuss this design, I'm really not sure if it is the right way to do this

Copy link

Choose a reason for hiding this comment

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

btw, you can use ObjectProvider to get rid of this @Autowired(required=false)

@saragluna
Copy link
Owner

Already merged in this PR Azure#23787. Closing this one now.

@saragluna saragluna closed this Sep 6, 2021
@moarychan moarychan deleted the feature/unify-azure-spring-credential branch November 17, 2021 01:56
saragluna pushed a commit that referenced this pull request Feb 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants