我尝试设置身份服务器4 + API + web场景,但无法获取用户在api中的身份验证。每个组件在我的VS解决方案中使用单独的项目。所有项目都在dotnetcore 2.0上。带有承载的.Net Core2上的IdentityServer4 - API不验证身份验证/定制策略处理程序
Startup.cs Identity Server的
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddCors();
services.AddIdentityServer(options =>
{
options.Events.RaiseSuccessEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseErrorEvents = true;
})
.AddInMemoryClients(Clients.Get())
.AddInMemoryIdentityResources(Resources.GetIdentityResources())
.AddInMemoryApiResources(Resources.GetApiResources())
.AddDeveloperSigningCredential()
.AddExtensionGrantValidator<Extensions.ExtensionGrantValidator>()
.AddExtensionGrantValidator<Extensions.NoSubjectExtensionGrantValidator>()
.AddTestUsers(TestUsers.Users);
TestUsers.Users
public class TestUsers
{
public static List<IdentityServer4.Test.TestUser> Users = new List<IdentityServer4.Test.TestUser>
{
new IdentityServer4.Test.TestUser{SubjectId = "818727", Username = "alice", Password = "alice",
Claims =
{
new Claim(JwtClaimTypes.Role, "UserEditor"),
new Claim(JwtClaimTypes.Name, "Alice Smith"),
new Claim(JwtClaimTypes.Email, "[email protected]"),
}
},
new IdentityServer4.Test.TestUser{SubjectId = "88421113", Username = "bob", Password = "bob",
Claims =
{
new Claim(JwtClaimTypes.Role, "Root"),
new Claim(JwtClaimTypes.Role, "Admin"),
new Claim(JwtClaimTypes.Role, "UserEditor"),
new Claim(JwtClaimTypes.Name, "Bob Smith"),
new Claim(JwtClaimTypes.Email, "[email protected]")
}
}
};
}
获得通过http://localhost:2266/connect/token一个indentityserver JWT承载令牌的作品,它包含了相关信息:
{ ... ... “角色”: “根”, “管理”, “UserEditor” ], “范围”: ... ], ... }
但是 - 在API端身份验证没有正确检查。
API Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext...
...
...
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:2266";
options.RequireHttpsMetadata = false;
options.ApiSecret = "secret";
options.ApiName = "MyApi";
});
services.AddCors(options =>
{
// this defines a CORS policy called "default"
options.AddPolicy("default", policy =>
{
policy.WithOrigins("http://localhost:44352")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
// custom policy attributes
services.AddAuthorization(options =>
{
options.AddPolicy("Root", policy => policy.Requirements.Add(new Models.Policies.MyPolicyRequirement("Root")));
options.AddPolicy("Admin", policy => policy.Requirements.Add(new Models.Policies.MyPolicyRequirement("Admin")));
options.AddPolicy("UserEdit", policy => policy.Requirements.Add(new Models.Policies.MyPolicyRequirement("UserEdit")));
});
services.AddSingleton<IAuthorizationHandler, Models.Policies.MyPolicyHandler>();
services.AddMvc();
// add swagger
...
}
策略验证 控制器/操作都标有授权属性,例如 [授权(策略= “根”)] 的典调试时会触发策略处理程序。
public class MyPolicyHandler : AuthorizationHandler<MyPolicyRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyPolicyRequirement requirement)
{
if (!context.User.Identity.IsAuthenticated)
return Task.CompletedTask;
if (context.User.Identities.FirstOrDefault().HasClaim(System.Security.Claims.ClaimTypes.Role, requirement.Policy))
{
context.Succeed(requirement);
return Task.CompletedTask;
}
return Task.CompletedTask;
}
}
验证失败,因为context.User.Identity.IsAuthenticated为假,则对象身份不具有权利要求为好。 看起来管道中缺少某些东西将我的承载认证转换为用户标识。
有什么建议吗?
您是否在管道中调用了“App.UseAuthentication”? – leastprivilege
对不起 - 忘了那部分。 IdentityServer启动配置部分包含: 'app.UseIdentityServer();' 配置API的Startup.cs部分: 'app.UseCors(“default”); app.UseAuthentication(); 应用程序。我的意思是API管道 – MStrojek
app.UseAuthentication(); app.UseMvc(); – leastprivilege