首页 文章

自定义身份验证asp.net核心web api

提问于
浏览
6

我想使用一个秘密密钥(api密钥)授权asp.net核心web api . 密钥将在Authorization标头中传递,如下所示,

ex. Authorization keytype;h43484344343bbhfdjfdfhj34343

我想编写一个中间件来从请求头读取此密钥,并调用内部api来验证密钥 .

在web api中,我们可以编写一个消息处理程序来执行此操作,但我是asp.net核心的新手 . 我看到了很多样本,但他们正在使用内置的JWT令牌认证 . 但是我想使用自己的密钥并解密此密钥并对数据库条目进行验证 .

任何人都可以建议一些代码示例如何做到这一点?

1 回答

  • 11

    我在使用asp核心1.1的解决方案中使用了这种方法 . 首先定义一个自定义方案:

    public static class Authentication
    {
        public const string Scheme = "Custom";
    }
    

    然后你必须继承 AuthenticationHandler<TOptions> . 以下是验证标头值的逻辑:

    public class MyAuthenticationHandler : AuthenticationHandler<MyOptions>
    {
        protected override Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            var authorizationHeader = Context.Request.Headers["Authorization"];
            if (!authorizationHeader.Any())
                return Task.FromResult(AuthenticateResult.Skip());
    
            var value = authorizationHeader.ToString();
            if (string.IsNullOrWhiteSpace(value))
                return Task.FromResult(AuthenticateResult.Skip());
    
            // place logic here to validate the header value (decrypt, call db etc)
    
            var claims = new[]
            {
                new Claim(System.Security.Claims.ClaimTypes.Name, "Bob")
            };
    
            // create a new claims identity and return an AuthenticationTicket 
            // with the correct scheme
            var claimsIdentity = new ClaimsIdentity(claims, Authentication.Scheme);
    
            var ticket = new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties(), Authentication.Scheme);
    
            return Task.FromResult(AuthenticateResult.Success(ticket));
        }
    }
    

    为了继承 AuthenticationHandler ,您必须创建一个选项类,在其中将 AuthenticationScheme -property设置为您正在使用的方案:

    public class MyOptions : AuthenticationOptions
    {
        AuthenticationScheme = Authentication.Scheme;
    }
    

    在此之后,您必须继承 AuthenticationMiddleware<TOptions> . 这将创建您在上一步中实现的处理程序:

    public class MyAuthenticationMiddleware : AuthenticationMiddleware<MyOptions>
    {
        public MyAuthenticationMiddleware(RequestDelegate next, IOptions<MyOptions> options, ILoggerFactory loggerFactory, UrlEncoder encoder) : base(next, options, loggerFactory, encoder)
        {
        }
    
        protected override AuthenticationHandler<MyOptions> CreateHandler()
        {
            return new MyAuthenticationHandler();
        }
    }
    

    为了轻松插入中间件,您可以定义以下扩展方法:

    public static IApplicationBuilder UseMyAuthentication(this IApplicationBuilder app, IConfigurationSection config)
    {
        return app.UseMyAuthentication(options => {});
    }
    
    private static IApplicationBuilder UseMyAuthentication(this IApplicationBuilder app, Action<MyOptions> configure)
    {
        var options = new MyOptions();
        configure?.Invoke(options);
    
        return app.UseMiddleware<MyAuthenticationMiddleware>(new OptionsWrapper<MyOptions>(options));
    }
    

    然后在你的 Startup 类中,你最终可以添加你的中间件:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseMyAuthentication(Configuration.GetSection("MyAuthenticationOptions"));
    
        // other stuff
    
        app.UseMvc();
    }
    

    然后在指定刚刚创建的方案的操作上添加 AuthorizeAttribute

    [Authorize(ActiveAuthenticationSchemes = Authentication.Scheme)]
    public IActionResult Get()
    {
        // stuff ...
    }
    

    有很多步骤,但希望这会让你前进!

相关问题