Az Func access HttpContext

Rob Bowman 216 Reputation points
2021-08-30T07:32:43.7+00:00

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-credentials" 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");
Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,248 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,455 questions
{count} vote

Accepted answer
  1. sadomovalex 3,626 Reputation points
    2021-09-08T14:53:05.24+00:00

    if we check the code of RolesRequiredHttpContextExtensions.ValidateAppRole - it basically works with claims from request:

            public static void ValidateAppRole(this HttpContext context, params string[] acceptedRoles)
            {
                if (acceptedRoles == null)
                {
                    throw new ArgumentNullException(nameof(acceptedRoles));
                }
    
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }
                else if (context.User == null || context.User.Claims == null || !context.User.Claims.Any())
                {
                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                }
                else
                {
                    // Attempt with Roles claim
                    Claim? rolesClaim = context.User.FindFirst(ClaimConstants.Roles);
    
                    // Fallback to Role claim name
                    if (rolesClaim == null)
                    {
                        rolesClaim = context.User.FindFirst(ClaimConstants.Role);
                    }
    
                    if (rolesClaim == null || !rolesClaim.Value.Split(' ').Intersect(acceptedRoles).Any())
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        string message = string.Format(CultureInfo.InvariantCulture, IDWebErrorMessage.MissingRoles, string.Join(",", acceptedRoles));
                        context.Response.WriteAsync(message);
                    }
                }
            }
    

    I.e. if you would be able to get claims from request you would probably be able to implement similar check by custom code. In HTTP-triggered Azure function we may get access to claims using ClaimsPrincipal. E.g. this is how we may get user name from ClaimsPrincipal:

    string currentUserName = ClaimsPrincipal.Current.Identity.Name;
    

    ClaimsPrincipal.Current has method IsInRole() - check can it be used in your case?

    0 comments No comments

0 additional answers

Sort by: Most helpful