简体   繁体   中英

How to enable multiple authentication in ASP.NET Core 3.1?

In my aspnet core 3.1 project I am using jwt for authentication. Issue is I am also using azure client to get vm size name list and it is also using Bearer token. For now testing I use AllowAnonymous and Bearer from azure everything works fine, but I need double authentication one is default for authenticated users and one for azure.

My azure helper class looks like:

        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;
        }

// GET Azure token if possible I need to use this token inside get azure vm size list

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();                                                                                    
}                    

// My controller which I am using this helper:

        [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);
        }      

// My startup class jwt configuration (maybe possible extend it and add multiple 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
                    };
                });     

To manage virtual machines you shouldn't use authorization on behalf of the users. So after that you should have one global authorization for your user and one authorization for the Azure portal for your application. I would recommend you to use Microsoft.Azure.Management.ResourceManager package to get Virtual Machines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM