我尝试设置身份服务器4 + API + Web方案,但无法在api中对用户进行身份验证。每个组件在我的VS解决方案中使用单独的项目。所有项目都在dotnetcore 2.0上。
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, "AliceSmith@email.com"),
}
},
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, "BobSmith@email.com")
}
}
};
}
获取indentityserver jwt bearer token通过http://localhost:2266/connect/token工作,它包含相关信息:
{ ... ... &#34;角色&#34;:[ &#34;根&#34 ;, &#34;管理&#34 ;, &#34; UserEditor&#34; ] &#34;范围&#34;:[ ... ] ... }
但是 - 在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
...
}
政策验证 控制器/动作用授权属性标记,例如 [授权(政策=&#34; Root&#34;)] 调试时会触发策略处理程序的代码。
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为false,对象标识也没有声明。 看起来管道中缺少某些东西可以将我的承载认证转换为用户身份。
有什么建议吗?
答案 0 :(得分:0)
终于找到了问题: 我有一个对Microsoft.IdentityModel.Tokens(5.2.0-preview1)的引用因为 一些加载签名证书的代码。
如果启用了该包,则验证失败。
我曾经开始自己验证令牌的签名证书,所以我需要那个组件,但我想所有这些都将在AddIdentityServerAuthentication部分自动处理?
所以政策检查不是问题。谢谢你让我从基地开始。