.Net Core自定义身份验证,使用带有Identity Server 4的API密钥

manvir_singh

我有一个使用JWT令牌进行身份验证的.NET Core 2.2 Web API。令牌由Identity Server 4在单独的API上生成。

所有的身份验证和授权都可以与JWT令牌一起正常工作。但是我需要扩展它以允许使用API​​密钥。如果提供了API密钥,我想加载该特定用户的声明,将其添加到请求中,并让Authorize属性处理设置的策略。

到目前为止,这里是我根据这里的建议所做的工作我的错误与链接的帖子完全相同,并且使用具有一组角色的GenericPrincipal对我也适用,但是我使用的是AuthorisationPolicies,在当前的实现中始终会出现401错误,这给我带来了类似于上面链接的错误。

启动文件

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

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));
    }
}

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

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

显然,我必须按照此处的说明将其设置AuthenticationType为“自定义ClaimsIdentity

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

带有.NET Web API的AngularJS:使用AD进行身份验证

具有自定义身份验证的ASP.NET Web API

在ASP.NET Core中使用Authorize属性和自定义Cookie身份验证

带有OWIN的ASP.NET Web Api-自定义身份验证

Identity Server 4 Swagger身份验证

.net核心自定义身份验证中的User.Identity.IsAuthenticated始终为false

带有自定义API密钥中间件的.Net Core JWT身份验证

自定义身份验证ASP.NET Core Web API

与自定义身份验证中的角色权限相比,ASP.NET Core Identity中的角色声明

ASP.NET Core使用具有Cookie身份验证的自定义身份验证处理程序

具有Windows身份验证的ASP.NET Core 2.1自定义RoleProvider

.NET Core 2使用Azure AD进行身份验证-自定义登录页面

带有ASP.NET Core 2.2的Identity Server 4

自定义函数中的asp.net API cookie身份验证

带有基于权限的身份验证的.NET Core Identity API

使用NGINX反向代理后面的docker + kubernetes在带有Identity Server 4的Blazor Server应用程序中添加身份验证和授权

在.NET Core Web API中使用自定义属性进行JWT身份验证

带有JWT的两个自定义身份验证API laravel

使用运行Identity Server 4的ASP.NET CORE 3身份验证服务器对ASP.NET MVC 5应用(目标.net 4.5)进行身份验证

具有IdentityServer4,Asp.Net Core身份和不带实体框架的自定义提供程序的Blazor WebAssembly身份验证

具有自定义身份验证类型的ASP.NET Core JWT

用户的AD身份验证失败时如何导航到“自定义访问被拒绝的页面”(带有OpenIDConnect Azure AD身份验证的.net 3.1核心)

.Net Core 3.1自定义身份验证

如何使用自定义身份验证和内存托管进行ASP.NET Web API集成测试

使用 Asp.net Core 2.1 和 Identity Server 4 的身份验证/授权

如何使用自定义 API 实现 .Net Core Identity

使用 React hooks、.NET Core Web API 和 SQL Server 实现身份验证和授权

带有 WooCommerce 身份验证的 WordPress 自定义 API

Identity Server 4 与 ASP.NET Core MVC 进行身份验证然后调用 Angular SPA