microsoft-identity-web icon indicating copy to clipboard operation
microsoft-identity-web copied to clipboard

[Bug] RequiredScope Attribute does not work with Azure Functions

Open TanyaMykhnevych opened this issue 2 years ago • 7 comments

Which version of Microsoft Identity Web are you using? 1.21.1

Where is the issue?

  • Web API
    • [x] Protected web APIs (validating scopes)

Is this a new or an existing app? This is a new app or an experiment.

Repro

        [RequiredScope("demo.read")]
        [RoleAuthorize(Role.Admin, Role.Basic)]
        [FunctionName(nameof(GetVersions))]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "v1/GetVersions")] GetVersionsQuery req,
            ILogger log, ClaimsPrincipal principal)
        {
            if (principal is null) throw new ArgumentNullException(nameof(principal));

            try
            {
                log.LogInformation("C# HTTP trigger function processed a request.");
                var id = await _mediator.Send(req);
                return new OkObjectResult(id);
            }
            catch (Exception ex)
            {
                log.LogError(ex, "Get Versions exception.");
                return new BadRequestObjectResult(ex.Message);
            }
        }

Expected behavior Required scope should work with Azure Functions

Actual behavior RequiredScope Attribute is ignored. VerifyUserHasAnyAcceptedScope works but is deprecated.

TanyaMykhnevych avatar Jan 05 '22 10:01 TanyaMykhnevych

@TanyaMykhnevych : how do you create your Azure function? Which generation of Azure functions is it? Did you follow a document that led you to use [RequiredScope]

jmprieur avatar Jan 05 '22 17:01 jmprieur

@jennyf19. Let's remove the obsolete attribute on VerifyUserHasAnyAcceptedScope until we have a good solution for Azure Functions

jmprieur avatar Jan 05 '22 18:01 jmprieur

@jmprieur It is Azure Functions runtime 3.0. I use nuget package "Microsoft.NET.Sdk.Functions" Version="3.0.7". I read this documentation: https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-protected-web-api-verification-scope-app-roles?tabs=aspnetcore. I just included package "Microsoft.Identity.Web" Version="1.21.1" and added this attribute to Function method Run. Maybe I should do something else? For example register something in Startup.

TanyaMykhnevych avatar Jan 06 '22 07:01 TanyaMykhnevych

@jmprieur Some additional information: the same behavior for .NET 6 and v4 Azure Functions runtime. RequiredScope Attribute is ignored.

TanyaMykhnevych avatar Jan 11 '22 10:01 TanyaMykhnevych

I came accross the same issue on .NET 6 and Microsoft.Identity.Web 1.23.1. In my case it's not on Azure Functions but on a locally hosted .NET API. The attribute is set in a Controller Action.

Ignored (every scope is being accepted): [RequiredScope("User.Example")]

Works as expected: HttpContext.VerifyUserHasAnyAcceptedScope("User.Example");

Example:

using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web.Resource;
using System.Collections.Generic;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using UniBE.AAIapi.DTO.Global;
using UniBE.AAIapi.Manager;

namespace UniBE.AAIapi.API.Controllers;
[Route("api/[controller]/[action]")]
[ApiController]
public class DigicertController : ControllerBase {
    // GET: api/<DigicertController>/<TestAuth>
    [EnableCors("LocalPolicy")]
    [Authorize]
    [RequiredScope("Digicert.DivisionCerts.Write")] <= Does not work -> being ignored
    [HttpGet]
    [ActionName("TestAuth")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [SupportedOSPlatform("windows")]
    public ActionResult TestAuth() {
        //HttpContext.VerifyUserHasAnyAcceptedScope("Digicert.DivisionCerts.Write"); <= Works as expected when included

        return Ok();
    }```

michaelpfister avatar Mar 30 '22 05:03 michaelpfister

Has the above ever been resolved??

I am also TRYING to use [RequiredScope( "whatever" )] to decorate an API method - but the attribute does nothing - it seems to be ignored!

Further, (and as stated above), the VerifyUserHasAnyAcceptedScope() method seems to be working, and indeed, reviewing the source code for the method, one can review exactly what is being checked and what exceptions are thrown.

However, the source code for the RequiredScope attribute seems to do nothing but save the required scope(s) - no checks (that I can see) are even being performed (I am obviously missing something)!

I have also tried suggestions as posted on StackOverFlow, but again, nothing suggested works: (other than do not use scopes and switch to policies):

  • https://stackoverflow.com/questions/70599417/why-requiredscope-attribute-doesnt-have-any-effect
  • https://stackoverflow.com/questions/73458122/using-microsoft-identity-web-requiredscope-to-verify-the-scopes-at-the-level-of

Any work-arounds, suggestions would be appreciated.

Lost in Scope !

bdcoder2 avatar Jan 14 '23 21:01 bdcoder2

Just jumping in this as I'm tackling something else (outside of Functions) related to this attribute.

The attribute doesn't actually do anything. You have to add the handler to the dependency injector with

services.AddRequiredScopeAuthorization();

That installs the handler that will do the actual scope validation on the controller/action with the attribute.

jimmywim avatar Jan 11 '24 12:01 jimmywim