首页 > 解决方案 > 通过 Azure AD 验证的 Swagger 使用 webapi 时出现“无效令牌”

问题描述

我尝试从 swagger (Swashbuckle) 客户端对我的 WebApi (dotnet core 3.1) 使用 AAD 身份验证。在我的 Startup 课程中,我的配置如下:

// Configure authentication
services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme)
        .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));

我对 AzureAd 的设置:

"AzureAd": {
 "Instance": "https://login.microsoftonline.com/",
 "ClientId": "xxxx-xxxxx1b",
 "Domain": "myoffice.onmicrosoft.com",
 "TenantId": "xxxxx-xxxxa5",
 "Scope": "api://xxxxxxxx-abc3cff48f1b/Full.Access",
 "ScopeDescription": "Full Access"
},

...

services.AddSwaggerGen(c =>
{
   c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
      {
          Type = SecuritySchemeType.OAuth2,
          In = ParameterLocation.Header,
          Flows = new OpenApiOAuthFlows()
          {
               Implicit = new OpenApiOAuthFlow
               {
                   TokenUrl = new Uri($"Configuration["AzureAd:Instance"]}/{Configuration["AzureAd:TenantId"]}/oauth2/v2.0/token"),
                   AuthorizationUrl = new Uri($"{Configuration["AzureAd:Instance"]}/{Configuration["AzureAd:TenantId"]}/oauth2/v2.0/authorize"),
                   Scopes =
                   {
                        {
                            Configuration["AzureAd:Scope"],Configuration["AzureAd:ScopeDescription"]
                        }
                   }
               }
           }
      });
  c.AddSecurityRequirement(new OpenApiSecurityRequirement
  {
      {
           new OpenApiSecurityScheme
           {
               Reference = new OpenApiReference
               {
                   Type = ReferenceType.SecurityScheme,
                   Id = "Bearer"
               }
            },
            Array.Empty<string>()
            }
        });
    });

在我的配置方法中:

 app.UseSwaggerUI(c =>
 {
    c.RoutePrefix = string.Empty;
    c.SwaggerEndpoint($"/swagger/{ApiVersion}/swagger.json", ApiName);
    c.OAuthClientId(Configuration["AzureAd:ClientId"]);
    c.OAuthScopeSeparator(" ");
 });

Swagger 使用我的凭据正确登录到 AAD,当我使用受[Authorize]令牌保护的路由时,我收到 401 错误并显示以下消息,从而正确发送到 API:

www-authenticate: Bearer error="invalid_token"error_description="The issuer 'https://login.microsoftonline.com/{tenantid}/v2.0' is invalid"

urlhttps://login.microsoftonline.com/{tenantid}/v2.0位于 iss 部分的令牌中。

怎么了?

标签: .net-coreazure-active-directoryswaggerswagger-uiswashbuckle.aspnetcore

解决方案


根据您的错误和代码,您没有告诉您的应用程序 ValidIssuer。所以你得到了错误。请在文件方法ConfigureServices中 添加以下代码startup.cs

services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
        
                    ValidIssuers = new[] {
                     
                    },                    
            });

例如

  • 为您的 Web API 配置 Azure AD。更多详细信息,请参阅文档

    一种。创建 Azure AD Web api 应用程序

    湾。 公开 API 在此处输入图像描述

    C。配置代码

    1. 配置文件
    "AzureAd": {
     "Instance": "https://login.microsoftonline.com/",
     "ClientId": "[Client_id-of-web-api-eg-2ec40e65-ba09-4853-bcde-bcb60029e596]",  
     "TenantId": "<your tenant id>"
    },
    
    1. 在 Stratup.cs 中添加以下代码
     services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
                 .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
    
             services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
             {
                 options.Authority += "/v2.0";
    
    
                 options.TokenValidationParameters = new TokenValidationParameters
                 {
                    /**
                     *  with the single-tenant application, you can configure your issuers 
                     *  with the multiple-tenant application, please set ValidateIssuer as false to disable issuer validation 
                    */
                     ValidIssuers = new[] {
                       $"https://sts.windows.net/{Configuration["AzureAD:TenantId"]}/",
                       $"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/v2.0"
    
                     },
    
                     ValidAudiences = new[]
                     {
                            options.Audience,
                            $"api://{options.Audience}"
                     }
    
                 };
    
             });
    
  • 配置招摇。更多详情,请参阅博客

    一种。创建 Azure Web 应用程序

    在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

    湾。配置 API 权限。关于如何配置,可以参考文档

    C。代码

    1. 安装 SDK

       <PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
      
    2. 配置文件

       "Swagger": {
           "ClientId": ""
        },
      
    3. 在 ConfigureServices 方法中将以下代码添加到 Startup.cs:

       services.AddSwaggerGen(o =>
           {
               // Setup our document's basic info
               o.SwaggerDoc("v1", new OpenApiInfo
               {
                   Title = "Protected Api",
                   Version = "1.0"
               });
      
               // Define that the API requires OAuth 2 tokens
               o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
               {
                   Type = SecuritySchemeType.OAuth2,
      
                   Flows = new OpenApiOAuthFlows
                   {
                       Implicit = new OpenApiOAuthFlow
                       {
                           Scopes = new Dictionary<string, string>
                           {
                               { "api://872ebcec-c24a-4399-835a-201cdaf7d68b/user_impersonation","allow user to access api"}
                           },
                           AuthorizationUrl = new Uri($"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/oauth2/v2.0/authorize"),
                           TokenUrl = new Uri($"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/oauth2/v2.0/token")
                       }
                   }
               });
      
               o.AddSecurityRequirement(new OpenApiSecurityRequirement{
               {
                   new OpenApiSecurityScheme{
                       Reference = new OpenApiReference{
                           Id = "oauth2",
                           Type = ReferenceType.SecurityScheme
                       }
                   },new List<string>()
                   }
               });
      
           });
      
    4. 将以下代码添加到 Configure 方法中:

       app.UseSwagger();
           app.UseSwaggerUI(c =>
           {
               c.OAuthClientId(Configuration["Swagger:ClientId"]);
               c.OAuthScopeSeparator(" ");
               c.OAuthAppName("Protected Api");
      
               c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
           });
      
  • 测试 在此处输入图像描述


推荐阅读