oauth-2.0azure-active-directoryazure-functionsmicrosoft-identity-web

Dotnet-Isolated Azure Functions - how to access HttpContext


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");

Solution

  • 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.