.net core 3.1 Bearer error="invalid_token", error_description="观众'空'无效" [英] .net core 3.1 Bearer error="invalid_token", error_description="The audience 'empty' is invalid"
问题描述
我有 3 个项目 1-Angular SPA 2-Web API 项目核心 3.1,3-IdentityServer 与核心 3.1但我收到以下错误
I have 3 projects 1- Angular SPA 2- Web API Project core 3.1, 3- IdentityServer with Core 3.1 But I am getting following error
> www-authenticate: Bearer error="invalid_token", error_description="The audience 'empty' is invalid"
这是我的 API 启动
This is my API startup
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
Identity server 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 配置
Angular SPA oidc config
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 和消息.但是里面没有观众.
I have 3 controllers and I added [Authorize] on each controller. Can anyone help me with this? I get the token generated successfully and when I am using the token to call the webapi it throwing 401 with message. But no audience is present in it.
推荐答案
我遇到了同样的问题,我的令牌中缺少 Aud 和 Iss.我需要它,因为在我的 Startup.cs 文件中,我将它们设置为验证所需.
I was facing the same issue, and ?I was missing Aud and Iss in my token. I needed that since in my Startup.cs file, I set them to be required for validation.
在您的令牌字符串中,我没有看到 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
};
});
下面是我的生成令牌方法:
Below is my generate token method:
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);
}
这篇关于.net core 3.1 Bearer error="invalid_token", error_description="观众'空'无效"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!