0
votes

I have setup an AAD-protected asp.net core 3.1 restapi web service by the following steps.

  1. Register a server app (HelloWorld) and then add a scope.

  2. Register a client app(domino-client) and create a secret. Then add the server app permission.

  3. Add AAD auth to asp.net core. I create a rest api project and do the following changes. (Config auth related service and middleware. Config controller.)

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddAuthentication(o =>
            {
                o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(o =>
            {
                o.Authority = "https://login.microsoftonline.com/{tenant_id}";
                o.Audience = "a1faffea-24c6-42ff-9586-ee86ec7b8e80";          // server app client id
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthentication();  // Add aad auth.

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    [Authorize]  // Enable auth.
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
          .....
        }
    }

  1. Then try to use postman to access the api.

Some parmas when accessing token.

  • Access token url: Got from Endpoint
  • Client ID: client app client id
  • Client Secret: client app secret
  • scope: server app scope

Howerer, I get 401 unauthoried error. Is something wrong with the process?

2

2 Answers

0
votes

You are using client credential flow to accessing your protected web api , the audience of access token is api://fxxxb30-xxx-xxx-xxxx-bcaae52203cf , so try to modify your AddJwtBearer options to(also notice you are using Azure AD V2.0 endpoint) :

.AddJwtBearer(o =>
 {
     o.Authority = "https://login.microsoftonline.com/{tenant_id}/v2.0"; <--AAD V2.0
     o.Audience = "api://a1faffea-24c6-42ff-9586-ee86ec7b8e80";   <--  add api//     
 });

Another problem is you are adding the delegate permission , so access token issued by client credential flow won't include the delegate permission , instead you should use delegate flows like authorization code flow .

0
votes

According to the details you provided, you want to use OAuth 2.0 client credentials flow to access the API protected by Azure AD. If so you need to define app role instead of scope in your server app.

The detailed steps are as below

  1. Create server app

  2. Define app role

    a. Select the application you want to define app roles in. Then select Manifest.

    b. Edit the app manifest by locating the appRoles setting and adding all your Application Roles. It should be like as below

    "appRoles": [
    {
    "allowedMemberTypes": [
      "Application"
    ],
    "displayName": "access the web api",
    "id": "47fbb575-859a-4941-89c9-0f7a6c30beac",
    "isEnabled": true,
    "description": "Consumer apps have access to web api.",
    "value": "Consumer"
    }
    ],
    
  3. Register a client app and create a secret.

  4. Add the app role for your client application enter image description here

  5. Configure web API

    a. Startup.cs

    public void ConfigureServices(IServiceCollection services)
      {
    services.AddAuthentication(x =>
          {
              x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
              x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
          })
        .AddJwtBearer(x =>
        {
            x.Authority = "https://login.microsoftonline.com/<tenant id>/v2.0";
            x.TokenValidationParameters = new TokenValidationParameters
            {
    
                ValidateIssuer = false,
                 ValidAudiences = new[] {"<app id>","<app id url>" }
            };
        });
          services.AddControllers();
      }
      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
      {
          if (env.IsDevelopment())
          {
              app.UseDeveloperExceptionPage();
          }
    
          app.UseHttpsRedirection();
    
          app.UseRouting();
    
          app.UseAuthentication();
          app.UseAuthorization();
    
          app.UseEndpoints(endpoints =>
          {
              endpoints.MapControllers();
          });
      }
    

    b. add [Authorize] in your API Controller to enable auth

  6. Test in postman

    a. Get Access token enter image description here

    b. Call API enter image description here