2

I have a dotnet 5 Azure Function (dotnet-isolated) that is triggered by an HTTP call.

The function will be called by a different Azure function app and I'd like to secure the target with Azure AD and use "client-credentations" OAuth2 flow.

I found an excellent sample that informs for my scenario at: Microsoft GitHub Sample

My problem is, the sample uses a WebApi app as the service. This has access to the HttpContext object uses an extension method in the Microsft.Identity.Web assembly called "ValidateAppRole"

My Azure function does have a parameter of type HttpRequestData. This has a headers property containing key value pairs. One of those keys is called "Authorization" and its value is the Access Token provided by Azure AD. I've run this token through jwt.ms and can confirm that the "Roles" collection contains the custom role I need to validate. So I know the information required is present; I just don't know how to check for it programmatically.

Since a dotnet-isolated Azure function doesn't seem to have access to the HttpContext object. How can a check equivalent to the following be made?

HttpContext.ValidateAppRole("CustomRoleName");
Rob Bowman
  • 7,632
  • 22
  • 93
  • 200
  • 1
    I'm actually working on a sample Functions app for doing this at the moment.. Might publish it in a few days if possible. Essentially you need to do the authentication in a custom middleware and assign the claims principal to the Items collection on the request data. Then you can do authorization against any claims that are there, including app permissions like you mentioned. There is no HttpContext because the call your Function receives is actually a GRPC call from the Functions runtime (which runs in a separate process and handles the HTTP request). – juunas Aug 31 '21 at 06:32
  • Thanks @juunas that makes sense. I'm starting to think my move to dotnet-isolated was a bad idea. In addition to this problem, I now also get a grpc timeout exception in some environments (but works ok in others). It seems like the dotnet-isolated option was perhaps made generally available prematurely – Rob Bowman Aug 31 '21 at 06:39
  • @RobBowman - I've not tried by myself the followed suggestion --- check if you can inject the `IHttpContextAccessor` in the required class to get the `HttpContext` You need to register the service via `builder.Services.AddHttpContextAccessor()` – user1672994 Aug 31 '21 at 08:58
  • I think @juunas is right - it's not possible with dotnet-isolated without development of custom middleware – Rob Bowman Aug 31 '21 at 14:57
  • 1
    @RobBowman Here's the sample if you are interested: https://github.com/juunas11/IsolatedFunctionsAuthentication – juunas Sep 01 '21 at 17:46
  • @juunas I think your sample code is the answer! Do you want to submit as answer to this SO question? – Rob Bowman Sep 02 '21 at 13:55

1 Answers1

5

I've made a sample Functions app for this: https://github.com/juunas11/IsolatedFunctionsAuthentication.

The sample includes two middleware: AuthenticationMiddleware and AuthorizationMiddleware. The former validates the JWT and creates a ClaimsPrincipal from it, while the latter checks for claims on the ClaimsPrincipal based on attributes set on the Function method.

You can see the full code in the GitHub repository. The authentication middleware sets the ClaimsPrincipal to the FunctionContext with:

context.Features.Set(new JwtPrincipalFeature(principal, token));

The authorization middleware can then get it from the same context object with:

var principalFeature = context.Features.Get<JwtPrincipalFeature>();

The code can then check for specific claims.

The same context object is also available within the Function methods. In the sample, attributes are used with middleware so that the Function code itself does not have to check for authorization.

juunas
  • 54,244
  • 13
  • 113
  • 149
  • 1
    So now in 2023 do we still need this kind of manual hookup? Seems like surely this is built-in by now, but I've been searching without success! – DeannaD Feb 20 '23 at 15:16
  • 1
    @DeannaD same here, i dont know why microsoft doesnt implement a formal way – Fredou Mar 06 '23 at 20:29