简体   繁体   English

.Net Core 自定义身份验证使用 API 密钥和 Identity Server 4

[英].Net Core Custom Authentication using API Keys with Identity Server 4

I have a .NET Core 2.2 Web API that authenticates with JWT tokens.我有一个使用 JWT 令牌进行身份验证的 .NET Core 2.2 Web API。 Tokens are generated by Identity Server 4 on a separate API.令牌由 Identity Server 4 在单独的 API 上生成。

All the authentication and authorisation works as expected with JWT tokens.使用 JWT 令牌,所有身份验证和授权都按预期工作。 But I need to extend this to allow usage of API keys.但我需要扩展它以允许使用 API 密钥。 If an API key is supplied, I want to load up the claims of that particular user, add it to the request and let Authorize attribute deal with the set policies.如果提供了 API 密钥,我想加载该特定用户的声明,将其添加到请求中并让 Authorize 属性处理设置的策略。

Here is what I have done so far following suggestions from here .以下是我根据此处的建议到目前为止所做的工作。 My error is exactly the same as the linked post and it works for me as well using GenericPrincipal with a set of roles but I am using AuthorisationPolicies and I always get 401 error with my current implementation, giving me errors similar to the link above.我的错误与链接的帖子完全相同,它也适用于我,并使用 GenericPrincipal 和一组角色,但我使用的是 AuthorisationPolicies 并且我当前的实现总是收到 401 错误,给我的错误类似于上面的链接。

Startup.cs启动文件

public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvcCore(options =>
        {
            options.Filters.Add(new RequireHttpsAttribute());
            options.Filters.Add(new AuthorizeFilter());
            options.Filters.Add(typeof(ValidateModelStateAttribute));
            options.AllowEmptyInputInBodyModelBinding = true;
        })
        .AddAuthorization(options =>
        {
            options.AddPolicies();
        })
        .AddJsonFormatters();

        services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = Configuration["Authentication:Authority"];
                options.RequireHttpsMetadata = true;
                options.ApiName = Configuration["Authentication:ApiName"];
            });
        services.AddCors();
    }

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseCors(policy =>
        {
            policy.AllowAnyHeader();
            policy.AllowAnyMethod();
            policy.AllowAnyOrigin();
        });

        app.UseHttpsRedirection();
        app.UseMiddleware<ApiKeyMiddleware>();
        app.UseAuthentication();
        app.UseMvc();
    }

AuthorizationPolicies.cs授权策略.cs

public static class AuthorizationPolicies
{
    public const string ReadUsersPolicy = "ReadUsers";
    public const string EditUsersPolicy = "EditUsers";

    public static void AddPolicies(this AuthorizationOptions options)
    {
        options.AddPolicy(ReadUsersPolicy, policy => policy.RequireClaim(Foo.Permission, Foo.CanReadUsers));
        options.AddPolicy(EditUsersPolicy, policy => policy.RequireClaim(Foo.Permission, Foo.CanEditUsers));
    }
}

ApiKeyMiddleware ApiKey中间件

public class ApiKeyMiddleware
{
    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    private readonly RequestDelegate _next;

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Path.StartsWithSegments(new PathString("/api")))
        {
            if (context.Request.Headers.Keys.Contains("ApiKey", StringComparer.InvariantCultureIgnoreCase))
            {
                var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
                await ValidateApiKey(context, _next, headerKey);
            }
            else
            {
                await _next.Invoke(context);
            }
        }
        else
        {
            await _next.Invoke(context);
        }
    }

    private async Task ValidateApiKey(HttpContext context, RequestDelegate next, string key)
    {
        var userClaimsService = context.RequestServices.GetService<IUserClaimsService>();
        List<string> permissions = (await userClaimsService.GetAllPermissionsForApiKey(key))?.ToList();
        if (permissions == null)
        {
            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            await context.Response.WriteAsync("Invalid Api Key");
            return;
        }

        ICollection<Claim> claims = permissions.Select(x => new Claim(FooClaimTypes.Permission, x)).ToList();
        var identity = new ClaimsIdentity(claims);
        var principal = new ClaimsPrincipal(identity);
        context.User = principal;
        await next.Invoke(context);
    }
}

UsersController.cs用户控制器.cs

[Authorize(AuthorizationPolicies.EditUsersPolicy)]
    public async Task<IActionResult> Put([FromBody] UserUpdateDto userUpdateDto)
    {
        ...
    }

显然,我必须按照此处的说明ClaimsIdentity AuthenticationType设置为Custom

var identity = new ClaimsIdentity(claims, "Custom");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Firebase和Identity的ASP.NET Core API身份验证 - ASP.NET Core API authentication using Firebase and Identity .NET 核心 Web API 身份验证和 .NET 身份 - .NET Core Web API Authentication and .NET Identity .NET 核心 API 密钥和身份集成 - .NET Core API keys & Identity integration .NET Core Identity Server 4身份验证VS身份验证 - .NET Core Identity Server 4 Authentication VS Identity Authentication 使用Identity Server在.Net Core Web API中授权 - Authorization in .Net Core Web API using Identity Server 在 .NET Core Web API 中使用自定义属性的 JWT 身份验证 - JWT Authentication using a custom attribute in .NET Core Web API 如何使用身份向 ASP.NET 核心最小 API 添加身份验证,但不使用 Azure? - How do I add authentication to an ASP.NET Core minimal API using Identity, but without using Azure? 为什么要使用Identity Server和asp.net core 2在基于令牌的身份验证上使用cookie - Why having cookies on token based authentication using Identity Server and asp.net core 2 带有ASP.NET CORE 1.0的Identity Server 3身份验证/授权 - Identity Server 3 Authentication/Authorization, with ASP.NET CORE 1.0 将 ASP.NET Core 标识与 IdentityServer4 结合使用 - 身份验证 - Using ASP.NET Core Identity with IdentityServer4 - Authentication
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM