-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Add Azure Authentication for Azure Services #18466
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
base: main
Are you sure you want to change the base?
Changes from 9 commits
2b26b50
098453a
917e0ad
0585d82
ec4fbd0
ba389dc
2e07d6b
a9b9215
83fc68d
179f767
66a863f
a05c811
51c804b
127f872
a0d8b4e
836ca00
f00d54e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| using OrchardCore.Modules.Manifest; | ||
|
|
||
| [assembly: Module( | ||
| Name = "OrchardCore.Azure", | ||
| Author = ManifestConstants.OrchardCoreTeam, | ||
| Website = ManifestConstants.OrchardCoreWebsite, | ||
| Version = ManifestConstants.OrchardCoreVersion, | ||
| Description = "Provides a way to manage Azure credentials", | ||
| Category = "Azure" | ||
| )] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <ItemGroup> | ||
| <FrameworkReference Include="Microsoft.AspNetCore.App" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\OrchardCore\OrchardCore.Abstractions\OrchardCore.Abstractions.csproj" /> | ||
| <ProjectReference Include="..\..\OrchardCore\OrchardCore.Azure.Core\OrchardCore.Azure.Core.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using OrchardCore.Azure.Core; | ||
| using OrchardCore.Modules; | ||
|
|
||
| namespace OrchardCore.Azure; | ||
|
|
||
| public class Startup : StartupBase | ||
| { | ||
| public override void ConfigureServices(IServiceCollection services) | ||
| { | ||
| services.AddAzureOptions(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| using Azure.Core; | ||
| using Azure.Identity; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.Extensions.Options; | ||
| using OrchardCore.Azure.Core; | ||
|
|
||
| namespace OrchardCore.Redis.Azure; | ||
|
|
||
| public sealed class AzureRedisTokenProvider : IRedisTokenProvider | ||
| { | ||
| private readonly IOptionsMonitor<AzureOptions> _options; | ||
| private readonly ILogger _logger; | ||
|
|
||
| public AzureRedisTokenProvider( | ||
| IOptionsMonitor<AzureOptions> options, | ||
| ILogger<AzureRedisTokenProvider> logger) | ||
| { | ||
| _options = options; | ||
| _logger = logger; | ||
| } | ||
|
|
||
| public async Task<string> GetTokenAsync() | ||
| { | ||
| var redisOptions = _options.Get("Redis"); | ||
|
|
||
| var scopes = redisOptions.GetProperty<string[]>("Scopes"); | ||
|
|
||
| if (scopes is null || scopes.Length == 0) | ||
| { | ||
| _logger.LogWarning("No scope configured for Azure Redis authentication, returning empty token."); | ||
|
|
||
| return null; | ||
| } | ||
|
|
||
| TokenCredential credential = redisOptions.AuthenticationType switch | ||
| { | ||
| AzureAuthenticationType.Default => new DefaultAzureCredential(), | ||
| AzureAuthenticationType.ManagedIdentity => new ManagedIdentityCredential(), | ||
| AzureAuthenticationType.AzureCli => new AzureCliCredential(), | ||
| _ => throw new NotSupportedException($"Authentication type {redisOptions.AuthenticationType} is not supported") | ||
| }; | ||
|
|
||
| var requestContext = new TokenRequestContext(scopes); | ||
|
|
||
| var result = await credential.GetTokenAsync(requestContext, CancellationToken.None); | ||
|
|
||
| return result.Token; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| using OrchardCore.Modules.Manifest; | ||
|
|
||
| [assembly: Module( | ||
| Name = "Azure Redis Cache", | ||
| Author = ManifestConstants.OrchardCoreTeam, | ||
| Website = ManifestConstants.OrchardCoreWebsite, | ||
| Version = ManifestConstants.OrchardCoreVersion, | ||
| Description = "Distributed cache using Azure Redis.", | ||
| Dependencies = | ||
| [ | ||
| "OrchardCore.Redis", | ||
| "OrchardCore.Azure", | ||
| ], | ||
| Category = "Distributed" | ||
| )] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <!-- NuGet properties--> | ||
| <Title>OrchardCore Redis Azure</Title> | ||
| <Description> | ||
| $(OCFrameworkDescription) | ||
|
|
||
| Provides Azure Redis features for configuration, cache, bus and lock. | ||
| </Description> | ||
| <PackageTags>$(PackageTags) OrchardCoreFramework Infrastructure</PackageTags> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <FrameworkReference Include="Microsoft.AspNetCore.App" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Azure.Identity" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\OrchardCore\OrchardCore.Abstractions\OrchardCore.Abstractions.csproj" /> | ||
| <ProjectReference Include="..\..\OrchardCore\OrchardCore.Azure.Core\OrchardCore.Azure.Core.csproj" /> | ||
| <ProjectReference Include="..\..\OrchardCore\OrchardCore.Infrastructure.Abstractions\OrchardCore.Infrastructure.Abstractions.csproj" /> | ||
| <ProjectReference Include="..\..\OrchardCore\OrchardCore.Module.Targets\OrchardCore.Module.Targets.csproj" /> | ||
| <ProjectReference Include="..\..\OrchardCore\OrchardCore.Redis.Abstractions\OrchardCore.Redis.Abstractions.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using OrchardCore.Modules; | ||
|
|
||
| namespace OrchardCore.Redis.Azure; | ||
|
|
||
| public sealed class Startup : StartupBase | ||
| { | ||
| public override void ConfigureServices(IServiceCollection services) | ||
| { | ||
| services.AddTransient<IRedisTokenProvider, AzureRedisTokenProvider>(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| using System.Net.Security; | ||
| using System.Security.Cryptography.X509Certificates; | ||
| using Microsoft.AspNetCore.DataProtection; | ||
| using Microsoft.AspNetCore.DataProtection.KeyManagement; | ||
| using Microsoft.Extensions.Caching.Distributed; | ||
| using Microsoft.Extensions.Caching.StackExchangeRedis; | ||
|
|
@@ -11,6 +12,7 @@ | |
| using OrchardCore.Environment.Cache; | ||
| using OrchardCore.Environment.Shell; | ||
| using OrchardCore.Environment.Shell.Configuration; | ||
| using OrchardCore.Environment.Shell.Scope; | ||
| using OrchardCore.Locking.Distributed; | ||
| using OrchardCore.Modules; | ||
| using OrchardCore.Redis.Options; | ||
|
|
@@ -55,6 +57,10 @@ public override void ConfigureServices(IServiceCollection services) | |
|
|
||
| services.Configure<RedisOptions>(options => | ||
| { | ||
| var protectorProvider = ShellScope.Services.GetRequiredService<IDataProtectionProvider>(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feels like a broken pattern to get and ambient shellscope. IF we can't access the services from this lambda then it's either wrong or it can't be a lambda.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. Don't like it either. We are doing the same thing in the Users module |
||
| var protector = protectorProvider.CreateProtector("RedisOptions"); | ||
|
|
||
| options.ConnectionIdentifier = protector.Protect(configuration); | ||
| options.Configuration = configuration; | ||
| options.ConfigurationOptions = configurationOptions; | ||
| options.InstancePrefix = instancePrefix; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cf previous comment, this should be in the OC.Azure module.