0

I'm developing Azure Functions using Visual Studio 2019 in .NET Core 3.1. I have to implement Azure AD authentication for these functions. I'm aware of how to use AD authentication in an ASP.NET Core 3.1 web app. But as there is no startup class provided by default in an Azure Function, how to implement the same logic?

I'm using this code in an ASP.NET Core 3.1 web app:

public void ConfigureServices(IServiceCollection services)
{
     services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApi(Configuration, "AzureAd");
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseAuthentication();
    app.UseAuthorization();
}

and adding [Authorize] tags in controller methods. But, I'm not able to figure out how to implement the same in an Azure Function. Here, I've currently set the authorization level as Anonymous like below

public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)
{
}

How to implement the Azure AD authentication here?

----UPDATE---- After adding the configurations suggested by Tiny-wa, still not able to figure out why is the Api responding with a 401 when I send a bearer token with it

enter image description here

Rahul Dev
  • 141
  • 2
  • 17

1 Answers1

2

I have a function contains an http trigger in it, before I enable authentication for the function, I can get response directly by calling url.

And I follow this document to enable the azure ad authentication for it.

Choose your function -> press into Authentication/Authorization tab -> check 'On'.

enter image description here

Then choose 'Log in with azure ad', click azure ad as Authentication providers, jump to a new page, choose express and create a new ad application. enter image description here enter image description here

After saving all configurations, it asks me to sign in when I call the url methoned above.

===============================UPDATE====================================

Http trigger can set different auth level by adding configuration and those are setting a different level as Anonymous, we need to add parameter in the request url. This document offers a sample and this one from microsoft offers detail.

enter image description here enter image description here

=============================update2=============================

I have found another solution which may suitable for you. Here's the sample.

After adding authenticate module in function code, you can expose the function as an api in azure ad. This makes your function app called with an access token. Of course I have tried the sample, here's my experience.

First, modify the configuration in Constants.cs, then create an azure ad app and expose an api. Next, add api permiss which exposed just now. Finally add client secret which is used to generate access token. Below are some screenshot about my action.

enter image description here enter image description here enter image description here enter image description here

Tiny Wang
  • 10,423
  • 1
  • 11
  • 29
  • What authorization level to be used in code? Earlier in .NET Core web app, I used to generate token using the token endpoint from azure portal which gave me a bearer token which I passed as an Authorization header. I was using client credential workflow with scope default to generate the token. Generating token is not the issue but how to validate the token and how to put [authorize] tags here. Can you explain with a working piece of code. – Rahul Dev Jan 05 '21 at 14:41
  • As you said above 'no startup class provided by default in an Azure', and in my opinion azure function is a code snippet, so my idea is enable authentication by configuration but not by code. So, **what's your purpose for enableing authentication**? If it's just making some of the users in your tenant could use this function, the document I provided in the answer can meet your requirement. I don't know why you are focusing on coding, or could you pls provide more details on your problem? – Tiny Wang Jan 05 '21 at 15:14
  • Just like in a .net core Web app you use [Authorize] tags on controller methods where you want the authentication to happen and not use the tags where you don't want them. But if you are doing a configuration, you can't add authentication to your desired controller methods, instead you are putting authentication on all controller methods. Is there any solution to it? – Rahul Dev Jan 11 '21 at 16:08
  • Good day, and with your response, you may want to set each trigger has its own authentication level, so I found [this document](https://jan-v.nl/post/adding-authentication-to-your-http-triggered-azure-functions/), it describes how to make http triggers have different auth level. – Tiny Wang Jan 12 '21 at 02:47
  • @RahulDev Any progress? And have you solved your problem? – Tiny Wang Jan 18 '21 at 09:40
  • I'm not able to open the api even after providing the bearer token. Edited my question. Please check. Please make me understand how this bearer token gets authenticated without code. In .net core web app, I had the code written in startup file as mentioned in my question. I'm generating the bearer token using the token endpoint url (OAuth 2.0 token endpoint (v2)) and passing the client_Id, client_secret, scope as .default and grant_type as client_credentials in the body as x-www-form-urlencoded format in postman – Rahul Dev Jan 19 '21 at 16:37
  • Based on the updated part, when enable authentication on trigger, we need use url like 'https://APPNAME.azurewebsites.net/api/FUNCTIONNAME?code=APIKEY' to call the function. And upon your screenshot, you wanna use access token to call an api, so I have an idea that you may create 2 function, one enable easy-auth, then users need to login first or use access token in request header so that they can visit function, another function stays in anonymous. Refer to [this](https://stackoverflow.com/questions/58763205/how-to-secure-azure-functions-with-oauth-for-both-humans-and-machines/58795499) – Tiny Wang Jan 20 '21 at 05:44
  • The code I used in the url in my screenshot came from portal -> function -> app keys -> host keys, it isn't an access token. – Tiny Wang Jan 20 '21 at 05:48
  • How is the token getting validated at the backend in .net core? what authentication scheme are you using? is it [HttpTrigger(AuthorizationLevel.System, "get", Route = null)] HttpRequest req, ILogger log) In the screenshot of the link you provided, it is not clear how is the token getting validated. – Rahul Dev Jan 20 '21 at 06:46
  • @RahulDev I'm not sure how it validated, but I think it done by SDK, because the code I used can't be modified but can just generated by system. – Tiny Wang Jan 20 '21 at 07:14
  • Generating token is not the issue here. Do you have any idea how to use microsoft.Identity.Web to validate the bearer tokens sent as authorization header with api request? – Rahul Dev Jan 20 '21 at 11:20