带有承载的.Net Core2上的IdentityServer4 - API未验证身份验证/自定义策略处理程序

时间:2017-10-10 09:34:49

标签: claims-based-identity identityserver4 policy bearer-token .net-core-2.0

我尝试设置身份服务器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,对象标识也没有声明。 看起来管道中缺少某些东西可以将我的承载认证转换为用户身份。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

终于找到了问题: 我有一个对Microsoft.IdentityModel.Tokens(5.2.0-preview1)的引用因为 一些加载签名证书的代码。

如果启用了该包,则验证失败。

我曾经开始自己验证令牌的签名证书,所以我需要那个组件,但我想所有这些都将在AddIdentityServerAuthentication部分自动处理?

所以政策检查不是问题。谢谢你让我从基地开始。