.net core 3.1 Bearer error="invalid_token", error_description="观众‘空’无效”

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

我有3个项目1-Angular SPA 2-Web API项目核心3.1,3-带有核心3.1的IdentityServer 但我收到以下错误

> www-authenticate: Bearer error="invalid_token", error_description="The audience 'empty' is invalid"

这是我的 API 启动

 public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<SchemaRegistryConfig>(Configuration.GetSection("SchemaRegistryConfig"));


            //identity server

            services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "https://localhost:5002/";
                    options.RequireHttpsMetadata = false;
                    options.Audience = "Api";
                });


            IdentityModelEventSource.ShowPII = true;

           
            services.AddCors(c =>
            {
                c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
            });

            services.AddMvc(config =>
            {
                config.Filters.Add(typeof(UnhandledExceptionFilter));
                config.EnableEndpointRouting = false;
            }).SetCompatibilityVersion(CompatibilityVersion.Latest);

            services.AddServices(Configuration);
            services.AddHealthChecksUI();                
            
          
        }

        
        [Obsolete]
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                
                app.UseHsts();
            }
            
            app.UseCors("AllowOrigin");

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();        

            app.UseHttpsRedirection();
            app.UseMvc();
        }

身份服务器config.cs

 public static class Config
    {
        public static IEnumerable<IdentityResource> IdentityResources =>
            new IdentityResource[]
            {               
              
                new IdentityResources.OpenId(),
                new IdentityResources.Email(),
                new IdentityResources.Profile(),
                new IdentityResources.Address(),

                new IdentityResource
                {
                    Name = "Api",
                    //UserClaims =
                    //{
                    //    "rc.garndma"
                    //}
                }
            };

       

        public static IEnumerable<Client> Clients =>
            new Client[]
            {
               
                new Client
                {
                    ClientName = "Code Flow with refresh tokens",
                    ClientId = "_client",

                    AccessTokenLifetime = 330,// 330 seconds, default 60 minutes
                    IdentityTokenLifetime = 45,

                    AllowAccessTokensViaBrowser = true,
                    RedirectUris = new List<string>
                    {
                        "http://localhost:4200/*******"
                    },
                    PostLogoutRedirectUris = new List<string>
                    {
                        "http://localhost:4200/*******"
                    },
                    AllowedCorsOrigins = new List<string>
                    {
                        "http://localhost:4200"
                    },

                    RequireClientSecret = false,

                    AllowedGrantTypes = GrantTypes.Code,
                    RequirePkce = true,
                    AllowedScopes = { "openid", "profile", "email", "Api" },

                    AllowOfflineAccess = true,
                    RefreshTokenUsage = TokenUsage.OneTimeOnly
                },
            };


        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("Api", "Invoice API")
                {
                    Scopes = { "invoice.read", "invoice.pay", "manage" }
                },
            };
        }

        public static List<ApiScope> ApiScopes()
        {
            return new List<ApiScope> {
            new ApiScope(name: "read",   displayName: "Reads your invoices."),
                new ApiScope(name: "pay",    displayName: "Pays your invoices."),
            };
        }
    }

身份服务器启动.cs

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

            var builder = services.AddIdentityServer()
                .AddInMemoryIdentityResources(Config.IdentityResources)
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryApiScopes(Config.ApiScopes())
                .AddInMemoryClients(Config.Clients)
                .AddTestUsers(TestUsers.Users);


            services.AddAuthentication();
                
            services.AddCors(options => options.AddPolicy("AllowAll", p => 
                p.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()));

            // not recommended for production - you need to store your key material somewhere secure
            builder.AddDeveloperSigningCredential();
        }

        public void Configure(IApplicationBuilder app)
        {
            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
           
            app.UseStaticFiles();
            app.UseRouting();
            app.UseCors("AllowAll");
            app.UseIdentityServer();
           
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }
    }

Angular SPA oidc 配置

export function configureAuth(oidcConfigService: OidcConfigService) {
  return () =>
    oidcConfigService.withConfig({
      stsServer: 'https://localhost:5002',
      redirectUrl: "http://localhost:4200/home",
      postLogoutRedirectUri: window.location.origin,
      clientId: '_client',
      scope: 'openid profile email offline_access Api',
      responseType: 'code',
      silentRenew: true,
      useRefreshToken: true    
     
    });

我的令牌有效负载是

我有3个控制器,我在每个控制器上添加了[授权]。 谁能帮我这个?我成功生成了令牌,当我使用令牌调用 webapi 时,它会抛出 401 消息。但里面没有观众。

c# .net-core jwt asp.net-identity identityserver4
3个回答
13
投票

我面临同样的问题,并且?我的令牌中缺少 Aud 和 Iss。我需要它,因为在我的 Startup.cs 文件中,我将它们设置为验证所需的。

在您的令牌字符串中我没有看到Aud声明

请参阅下面的两个代码:

Startup.cs中的ConfigureServices方法

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidateIssuer = true,
                    --> ValidateAudience = true, <--
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["Jwt:Issuer"],
                    ValidAudience = Configuration["Jwt:Audience"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"])),
                    ClockSkew = TimeSpan.Zero
                };
            });

以下是我的生成令牌方法:

    private string GenerateToken(UserViewModel loginViewModel)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, loginViewModel.UserName),
            new Claim("fullName", loginViewModel.FirstName + " " + loginViewModel.LastName),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            new Claim(JwtRegisteredClaimNames.Aud, _configuration["Jwt:Audience"]),
            new Claim(JwtRegisteredClaimNames.Iss, _configuration["Jwt:Issuer"])
        };

        var token = new JwtSecurityToken(
            issuer: _configuration["Issuer"],
            audience: _configuration["Audience"],
            claims: claims,
            expires: DateTime.Now.AddMonths(2),
            signingCredentials: credentials
            );

        return new JwtSecurityTokenHandler().WriteToken(token);
    }

0
投票

通过在以下位置添加行

ValidateAudience = false
来关闭受众验证:

.AddJwtBearer("Bearer", options =>
    {
     options.Authority = "https://localhost:5002/";
     options.RequireHttpsMetadata = false;
     options.Audience = "Api";
     options.ValidateAudience = false;
    });

-1
投票

对我来说,我必须删除以下内容

//services.AddAuthentication("Bearer")
//    .AddIdentityServerAuthentication("Bearer", options =>
//    {
//        options.Authority = identityServerUrl;
//        options.RequireHttpsMetadata = false;
//        options.ApiName = "bankOfDotNetApi";
//        //options.TokenValidationParameters = new TokenValidationParameters();
//    });

//services.AddAuthorization(options =>
//{
//    options.AddPolicy("bankOfDotNetApi", policy =>
//    {
//        policy.RequireAuthenticatedUser();
//        policy.RequireClaim("scope", "bankOfDotNetApi");
//    });
//});

并添加以下代码。注意 ValidateAudience = false。这就是不同之处。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.Authority = identityServerUrl;
    options.RequireHttpsMetadata = false;
    options.Audience = "bankOfDotNetApi";
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ////////////////////////////////////////////////////////
        // The following made the difference.  
        ////////////////////////////////////////////////////////
        ValidateAudience = false,
    };
});
© www.soinside.com 2019 - 2024. All rights reserved.