使用通过Azure AD认证的Swagger的webapi时,“无效令牌”

问题描述

我尝试通过swagger(Swashbuckle)客户端在WebApi(dotnet核心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>()
            }
        });
    });

在我的Configure方法中:

 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"

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

怎么了?

解决方法

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

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

例如

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

    a。创建Azure AD Web API应用程序

    b。 Expose API enter image description here

    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

    a。创建Azure Web应用程序

    enter image description here enter image description here enter image description here

    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");
           });
      
  • 测试 enter image description here

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...