HttpContext用户声明为空



我以前有一个使用IdentityServer和.Net Core 2.2 的工作项目

我最近对该项目的.Net版本进行了升级,从Core 2.2升级到.Net 5。还将每个软件包更新为最新版本。对我的代码做了一些调整,最终消除了所有的错误。我正在我的WEB API上测试我的Identity服务器功能,由于某些原因,HttpContext.User.Claims返回空。

这是我的代码。

public Guid? CurrentUserId
{
get
{
var claimNameIdentifier = User.Claims.FirstOrDefault(a => a.Type == ClaimTypes.NameIdentifier)?.Value;
return claimNameIdentifier != null ? Guid.Parse(claimNameIdentifier) : (Guid?)null;
}
}

我在一个基本控制器上有这个,由我的端点控制器实现,以获取访问我的端点的JWT上的用户id。不确定这是否是由于更新,因为这是以前的工作。

这是我的身份服务器配置

public static IEnumerable<IdentityResource>  IdentityResources =>
new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
public static IEnumerable<ApiResource> ApiResources =>
new List<ApiResource>
{
new ApiResource
{
Name = "ssi.api",
DisplayName = "Standing Settlement Instructions API"
}
};
public static IEnumerable<ApiScope> ApiScopes =>
new List<ApiScope>
{
new ApiScope
{
Name = "ssi.api",
DisplayName = "Standing Settlement Instructions API"

}
};
public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
ClientId = "ssi.front",
ClientName = "SSI Client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
// secret for authentication
ClientSecrets =
{
new Secret("my secret".Sha256())
},
// scopes that client has access to
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"ssi.api",
JwtClaimTypes.Role
},
AccessTokenLifetime = 14400,
AllowOfflineAccess = true,
}
};

以下是我的ConfigureServices的样子:

// Database
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer("Server=localhost; Database = SsiDB; Integrated Security = SSPI; MultipleActiveResultSets=true;"));
#region Identity
services.AddIdentity<User, Role>(options =>
{
options.Password.RequiredLength = 8;
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.User.RequireUniqueEmail = true;
})
.AddRoles<Role>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
var identityBuilder = services.AddIdentityServer()
.AddInMemoryPersistedGrants()
.AddInMemoryClients(IdentityConfig.Clients)
.AddInMemoryApiResources(IdentityConfig.ApiResources)
.AddInMemoryApiScopes(IdentityConfig.ApiScopes)
.AddAspNetIdentity<User>();
identityBuilder.Services.AddTransient<IResourceOwnerPasswordValidator, OwnerPasswordValidator>();
identityBuilder.Services.AddTransient<IProfileService, IdentityProfileService>();
identityBuilder.AddSigningCredential(new X509Certificate2("StandingSettlementInstructionsIdentityAuth.pfx", "", X509KeyStorageFlags.MachineKeySet)); //release
#endregion
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = appSettings.ApiUrl;
options.Audience = "ssi.api";
options.RequireHttpsMetadata = false;
});

这是我配置的

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHsts();
string appDataPath = Directory.GetCurrentDirectory() + @"AppData";
if (!Directory.Exists(appDataPath))
Directory.CreateDirectory(appDataPath);
app.UseSwaggerUI(o =>
{
o.DocumentTitle = "Standing Settlement Instructions Api Documentation";
o.RoutePrefix = "api-docs";
o.SwaggerEndpoint("/swagger/v1/swagger.json", "Version 1");
});
app.UseSwagger();
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<NotificationHubService>("/NotificationHubService");
});
app.Run((context =>
{
context.Response.Redirect("api-docs");
return Task.CompletedTask;
}));
}

我尝试过的东西:

  • 将其添加到ConfigureServiceservices.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();上,并在我的基本控制器上使用。相同的结果
  • 根据一些谷歌搜索重新安排对Configure方法的调用
  • 增加了对API资源和API范围的声明。相同的结果

一些观察。访问localhost/.aknowledge/openid-configuration显示空的支持声明,当我在API Resource或API Scopes上添加声明时,它确实出现在其中,但在提取声明时仍然会出现相同的问题。还是空的。

如有任何帮助,我们将不胜感激。我在这件事上一直很紧张。谢谢

调试索赔问题的第一步是实际查看访问令牌实际包含什么?使用类似的工具https://jwt.io/这样做。

然后,Microsoft和IdentityServer对索赔的名称有不同的意见,因此您需要通过使用来指出哪种索赔是名称索赔

.AddJwtBearer(opt =>
{
opt.TokenValidationParameters.RoleClaimType = "roles";
opt.TokenValidationParameters.NameClaimType = "name";
...

为了补充这个答案,我写了一篇博客文章,详细介绍了这个主题:调试ASP.NET Core中的JwtBearer声明问题和排除ASP.NET Core 中的JwtBearer身份验证问题

最新更新