【问题标题】:'Invalid token' when using webapi thru Swagger authenticated by Azure AD将 Web api 与由 Azure AD 验证的 Swagger 一起使用时出现“无效令牌”
【发布时间】:2020-12-10 01:03:51
【问题描述】:

我尝试在我的 WebApi (dotnet core 3.1) 上从 swagger (Swashbuckle) 客户端使用 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] 保护的路由时,令牌被正确地发送到 API,因为我收到带有以下消息的 401 错误:

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

url https://login.microsoftonline.com/{tenantid}/v2.0 在 iss 部分的令牌中。

怎么了?

【问题讨论】:

    标签: .net-core azure-active-directory swagger swagger-ui swashbuckle.aspnetcore


    【解决方案1】:

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

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

    例如

    • 为您的 Web API 配置 Azure AD。更多详情请参考document

      一个。创建 Azure AD web api 应用程序

      b. Expose 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}"
                       }
      
                   };
      
               });
      
    • 配置招摇。更多详情请参考blog

      一个。创建 Azure Web 应用程序

      b.配置 API 权限。关于如何配置,可以参考document

      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");
             });
        
    • 测试

    【讨论】:

    • 非常感谢@Jim Xu,你拯救了我的一天!只有带有services.Configure&lt;JwtBearerOptions&gt; 的部分丢失了,我自己也不会发明它!
    • @Jim Xu。谢谢。这对我帮助很大。 :)
    猜你喜欢
    • 1970-01-01
    • 2021-08-10
    • 2019-11-14
    • 1970-01-01
    • 2022-11-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    相关资源
    最近更新 更多