问题
I am creating a C# Azure Function, and I am getting the access token using Client ID, Client Key and Tenant ID for operation on Batch Service and Management. Can I use MSI authentication to get access token.
I am using the following APIs:
- List Subscription -
GET https://management.azure.com/subscriptions?api-version=2019-06-01
(docs) - List Batch Accounts from subsciption id:
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Batch/batchAccounts?api-version=2019-08-01
(docs) - List Pools based on batch account:
GET {batchUrl}/pools?api-version=2019-08-01.10.0
(docs) - List Jobs based on batch account:
GET {batchUrl}/jobs?api-version=2019-08-01.10.0
(docs) - Delete Pool based on pool id:
DELETE {batchUrl}/pools/{poolId}?api-version=2019-08-01.10.0
(docs) - Delete Job based on job id:
DELETE {batchUrl}/jobs/{jobId}?api-version=2019-08-01.10.0
(docs)
They work fine, but due to security reasons in the organisation I can not use client id and client key. And even storing them in the key vault is also not allowed now. Is there a way to use MSI ? - The code will be running on a serverless platform i.e. Azure Functions.
回答1:
Yes you can achieve that by doing the below steps:
- Setting Up the Web API
The Azure hosted Web API is set to use Azure AD authentication based on JWT token.Suppose I created an AD application and
ClientId
set up as shown below. Any request to the Web API needs a valid token from the Azure AD application in the request header. Here is the sample code to configure the web api :
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Audience = Configuration["AzureAd:ClientId"];
options.Authority =
$"{Configuration["AzureAd:Instance"]}{Configuration["AzureAd:TenantId"]}";
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseAuthentication();
app.UseMvc();
}
Now you can write the methods in your web api to call all the management api which you have mentioned above.
- Second step you need to perform is to enable the MSI on Azure Function.
Managed Serviced Identity (MSI) can be turned on through the Azure Portal. Under ‘Platform features’ for an Azure Function select ‘Identity’ as shown below and turn it on for System Assigned.
To authenticate with the Web API, we need to present a token from the AD application. Any service principal on the AD can authenticate and retrieve token this and so can out Azure Function with the Identity turned on. Usually authenticating with the Azure AD requires a Client ID/Secret or ClientId?Certificate combination. However, with MSI turned on, Azure manages these credentials for us in the background, and we don’t have to manage it ourselves. By using the AzureServiceTokenProvider class from the Microsoft.Azure.Services.AppAuthentication, NuGet package helps authenticate an MSI enabled resource with the AD.
To access the API, we need to pass the token from AD application as a Bearer token, as shown below.
var target = "<AD App Id of Web API>";
var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync(target);
var wc = new System.Net.Http.HttpClient();
wc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var result = await wc.GetAsync("<Secured API URL>");
you can check this tutorial for more elaborated steps:
https://youtu.be/HVruBWuKnYw
https://youtu.be/r4QFBsT2YE8
https://www.rahulpnath.com/blog/how-to-authenticate-azure-function-with-azure-web-app-using-managed-service-identity/
Hope it helps.
来源:https://stackoverflow.com/questions/59212231/how-to-use-msi-authentication-instead-of-providing-client-id-and-client-key-for