使用 C# 代码调用 API 时出现错误 Bearer error="invalid_token"

问题描述 投票:0回答:1

我正在学习使用 Azure AD 身份验证来验证 API,这是我在 MVC 端配置的代码

public async Task<IEnumerable<Todo>> GetAsync()
{
    await PrepareAuthenticatedClient();

    var response = await _httpClient.GetAsync($"{ _TodoListBaseAddress}/api/todolist");

    if (response.StatusCode == HttpStatusCode.OK)
    {
        var content = await response.Content.ReadAsStringAsync();
        IEnumerable<Todo> todolist = JsonConvert.DeserializeObject<IEnumerable<Todo>>(content);

        return todolist;
    }

    throw new HttpRequestException($"Invalid status code in the HttpResponseMessage: {response.StatusCode}.");
}

private async Task PrepareAuthenticatedClient()
{
    var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { _TodoListScope });
    Debug.WriteLine($"access token-{accessToken}");
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}

MVC

appsettings.json
文件

{   
    "AzureAdB2C":  
    {
        "Instance": "https://login.microsoftonline.com/",     
        "Domain": "xxxx.com",     
        "TenantId": "4d5c2d64-35d8-4200-805e-xxxxxx11e",     
        "SignedOutCallbackPath": "/signout",     
        "ClientSecret": "MMA8Q\~T\~KwXpSqDscijieKycv7Zxxxxxxxxxt",     
        "ClientId": "c8db825e-be17-4943-b2e5-caxxxxx5"   
    },   
    "TodoList": 
    {     
         "TodoListScope": "tasks.read",     
         "TodoListBaseAddress": "https://localhost:44332"   
    },   
    "Logging": 
    {     
        "LogLevel":
        {       
            "Default": "Information",       
            "Microsoft": "Warning",       
            "Microsoft.Hosting.Lifetime": "Information"     
        }   
    },   
    "AllowedHosts": "\*" 
}

Web API

Startup
文件:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApi(options => {Configuration.Bind("AzureAdB2C", options);

    options.TokenValidationParameters = new TokenValidationParameters()
     {
         ValidateLifetime = true,
         ValidateIssuerSigningKey = true,
         ValidateIssuer = true,
         ValidateAudience = true,
         ValidIssuer = "https://login.microsoftonline.com/",
         ValidAudience = "api://c8db825e-be17-4943-b2e5-caf39xxxx",
         IssuerSigningKey =
             new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                 Configuration["AzureAdB2C:ClientSecret"])),
     };
     options.Events = new JwtBearerEvents
     {
         OnAuthenticationFailed = context =>
         {
             // Log detailed information about the failure
             Console.WriteLine($"Authentication failed: {context.Exception}");
             return Task.CompletedTask;
         },
         OnChallenge = context =>
         {
             // Log detailed information about the challenge
             Console.WriteLine($"Challenge: {context.Error}, {context.ErrorDescription}");
             return Task.CompletedTask;
         }
     };
 },
 options => { Configuration.Bind("AzureAdB2C", options); });
 
    services.AddControllers();
}

Web API

appsettings.json
:

{   
    "AzureAdB2C": 
    {     
        "Instance": "https://login.microsoftonline.com/",     
        "Domain": "xxxx.com",     
        "ClientId": "aeaaab9e-1040-4edf-9f31-5adc3xxxx",     
        "SignedOutCallbackPath": "/signout/",     
        "TenantId": "4d5c2d64-35d8-4200-805e-9cdddxxxx",     
        "ClientSecret": "MMA8Q~T~KwXpSqDscijieKycv7ZWspsnxxxx"   
    },   
    "Kestrel": 
    {     
        "Endpoints": 
        {       
            "Http": 
            {         
                "Url": "https://localhost:44332"       
            }     
        }   
    },   
    "Logging": 
    {     
        "LogLevel": 
        {       
            "Default": "Warning"     
        }   
    },   
    "AllowedHosts": "*" 
}

这是我用来在线获取代码的存储库https://github.com/learnsmartcoding/azure-ad-b2c-authentication-tutorial为Azure中的MVC应用程序和Web API添加了应用程序注册配置

我希望 API 应该接受从 Azure AD 用户生成的令牌。我尝试配置在网上找到的详细信息,但 API 不接受不记名令牌

authentication .net-core azure-active-directory
1个回答
0
投票

我创建了一个 ASP。 NET Core API 并使用 Swagger UI 集成 Azure AD 身份验证。

我将以下代码添加到 Program.cs 文件中。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(
    o =>
    {
        o.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Swagger Azure Ad", Version = "v1" });
        o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Name = "oauth2.0",
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = new Uri(builder.Configuration["SwaggerAAD:AuthorizationUrl"]),
                    TokenUrl = new Uri(builder.Configuration["SwaggerAAD:TokenUrl"]),
                    Scopes = new Dictionary<string, string>
                    {
                        {builder.Configuration["SwaggerAAD:Scope"],"Access API as User" }
                    }
                }
            }
        });
        o.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference=new OpenApiReference{Type=ReferenceType.SecurityScheme,Id="oauth2"}
                },
                new []{builder.Configuration["SwaggerAAD:Scope"]}
            }
        });
    });
app.UseSwaggerUI(
        o =>
        {
            o.OAuthClientId(builder.Configuration["SwaggerAAD:ClientId"]);
            o.OAuthUsePkce();
            o.OAuthScopeSeparator(" ");
        });
}

下面是Program.cs的完整代码:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Web;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(
    o =>
    {
        o.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Swagger Azure Ad", Version = "v1" });
        o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Name = "oauth2.0",
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = new Uri(builder.Configuration["SwaggerAAD:AuthorizationUrl"]),
                    TokenUrl = new Uri(builder.Configuration["SwaggerAAD:TokenUrl"]),
                    Scopes = new Dictionary<string, string>
                    {
                        {builder.Configuration["SwaggerAAD:Scope"],"Access API as User" }
                    }
                }
            }
        });
        o.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference=new OpenApiReference{Type=ReferenceType.SecurityScheme,Id="oauth2"}
                },
                new []{builder.Configuration["SwaggerAAD:Scope"]}
            }
        });
    });
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(
        o =>
        {
            o.OAuthClientId(builder.Configuration["SwaggerAAD:ClientId"]);
            o.OAuthUsePkce();
            o.OAuthScopeSeparator(" ");
        });
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

appSettings.json

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<YourDomain>.onmicrosoft.com",
    "TenantId": "<YourTenantID>",
    "ClientId": "<ClientId>",
    "CallbackPath": "/signin-oidc",
    "Scopes": "access_as_user"
  },
  "SwaggerAAD": {
    "AuthorizationUrl": "https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/authorize",
    "TokenUrl": "https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/token",
    "Scope": "https://graph.microsoft.com/.default",
    "ClientId": "<ClientId>"
  }

我为 Azure AD 创建了两个应用程序注册,一个用于 Web API,另一个用于 Swagger 客户端。

在 API 应用程序注册中,转到身份验证 -> 添加平台 -> Web -> 重定向 URI。

https:Localhost:Port/singin-oidc

enter image description here

在 api 中转到公开 Api -> 添加范围。我添加了以下详细信息。

enter image description here

在 swaggerclient 应用程序注册中转到身份验证 -> 添加平台 -> 单页应用程序 -> 重定向 URL,如下所示。

https:Localhost:Port/swagger/oauth2-redirect.html

enter image description here

在 swaggerclient 中转到 API 权限 -> 添加权限 -> 我的 API -> api -> 权限,选择您的范围,如下所示。

enter image description here

enter image description here

运行后点击授权按钮。

enter image description here

选择范围并单击授权按钮。

enter image description here

如下图即登录成功。

enter image description here

输出

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.