如何在 ASP.NET Core 3.1 中启用多重身份验证?
Posted
技术标签:
【中文标题】如何在 ASP.NET Core 3.1 中启用多重身份验证?【英文标题】:How to enable multiple authentication in ASP.NET Core 3.1? 【发布时间】:2020-08-31 01:32:49 【问题描述】:在我的 aspnet core 3.1 项目中,我使用 jwt 进行身份验证。问题是我也在使用 azure 客户端来获取 vm 大小名称列表,并且它也在使用 Bearer 令牌。现在测试我使用 azure 中的 AllowAnonymous 和 Bearer 一切正常,但我需要双重身份验证,一个是经过身份验证的用户的默认设置,一个是 azure 的默认设置。
我的天蓝色助手类看起来像:
public static async Task<List<string>> GetAzureVmSizeList(string clientId, string clientSecret, string tenantId, string subscriptionId, string location)
var instanceIds = new List<string>();
var vmSizes = await VirtualMachineSizes(clientId, clientSecret, tenantId, subscriptionId, location);
foreach (var vmSize in vmSizes.Where(x => x.NumberOfCores >= 2 && x.MemoryInMB >= 2048))
instanceIds.Add(vmSize.Name);
return instanceIds;
private static async Task<IEnumerable<VirtualMachineSize>> VirtualMachineSizes(string clientId, string clientSecret, string tenantId,
string subscriptionId, string location)
AzureCredentials credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(
clientId,
clientSecret,
tenantId,
AzureEnvironment.AzureGlobalCloud);
RestClient restClient = RestClient.Configure()
.WithEnvironment(AzureEnvironment.AzureGlobalCloud)
.WithCredentials(credentials)
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.Build();
ComputeManagementClient client = new ComputeManagementClient(restClient.Credentials)
SubscriptionId = subscriptionId
;
var vmSizes = await client.VirtualMachineSizes.ListAsync(location);
return vmSizes;
// 如果可能,获取 Azure 令牌我需要在获取 azure vm 大小列表中使用此令牌
public static async Task<string> GetToken(string azureUrl, string clientId, string
clientSecret)
var url = $"https://login.microsoftonline.com/azureUrl/oauth2/v2.0/token";
var credentials = new Dictionary<string, string>
"client_id", clientId,
"client_secret", clientSecret,
"scope", "https://management.azure.com/.default",
"grant_type", "client_credentials"
;
var client = new HttpClient();
var req = new HttpRequestMessage(HttpMethod.Post, url) Content = new
FormUrlEncodedContent(credentials) ;
var res = await client.SendAsync(req);
var result = res.Content.ReadAsStringAsync().Result;
var tokenObject = JObject.Parse(result);
var token = tokenObject["access_token"];
return token.ToString();
// 我正在使用此助手的控制器:
[AllowAnonymous] // it should be [Authorize]
[HttpGet("azurevm/projectName")]
public async Task<IActionResult> GetAzureList(string projectName)
var credentials = await _context.Projects
.Join(_context.CloudCredentials, project => project.CloudCredentialId, cloud
=> cloud.Id,
(project, cloud) => new project, cloud)
.Where(@t => @t.cloud.IsAzure
&& @t.project.Name == projectName).Select(x =>
new
azureLocation = x.cloud.AzureLocation,
azureClientId = x.cloud.AzureClientId,
azureClientSecret = x.cloud.AzureClientSecret,
azureSubscriptionId = x.cloud.AzureSubscriptionId,
azureTenantId = x.cloud.AzureTenantId,
azureUrl = x.cloud.AzureUrl
).FirstOrDefaultAsync();
if (credentials == null)
return BadRequest($"projectName is not Azure based");
var result = await AzureHelper.GetAzureVmSizeList(credentials.azureClientId,
credentials.azureClientSecret,
credentials.azureTenantId,
credentials.azureSubscriptionId,
credentials.azureLocation);
if (result == null)
return BadRequest($"projectName is not Azure based");
return Ok(result);
//我的启动类jwt配置(或许可以扩展,添加多个jwt)
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.TokenValidationParameters = new TokenValidationParameters
ValidateIssuerSigningKey = true,
IssuerSigningKey =
new SymmetricSecurityKey(
Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
;
);
【问题讨论】:
【参考方案1】:要管理虚拟机,您不应代表用户使用授权。因此,在那之后,您应该为您的用户获得一项全局授权,并为您的应用程序获得一项 Azure 门户授权。我建议您使用 Microsoft.Azure.Management.ResourceManager 包来获取虚拟机。
【讨论】:
其实我已经在使用 **Microsoft.Azure.Management.ResourceManager.Fluent; Microsoft.Azure.Management.ResourceManager.Fluent.Authentication; Microsoft.Azure.Management.ResourceManager.Fluent.Core; ** 所以不要使用 JWT 令牌。准备这样的凭据: var credentials = new AzureCredentialsFactory() .FromServicePrincipal(servicePrincipleCredentials.ClientId, servicePrincipleCredentials.ClientSecret, servicePrincipleCredentials.TenantId, AzureEnvironment.AzureGlobalCloud);然后将其传递给身份验证方法 Azure.Configure().Authenticate(credentials) Azure 的凭据可以存储在应用程序设置中。我建议你在 Azure 应用服务中使用 Key Vault 或应用程序设置。不要直接将机密存储在 appsettings.json 中。以上是关于如何在 ASP.NET Core 3.1 中启用多重身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
仅在 IIS 中发布时,在 ASP.net Core 3.1 WebAPI 中启用 CORS 时出错
在 ASP.NET Core 3.1 中处理多环境的 CORS 策略
如何在 ASP.NET Core 3.1 中使用 Java?