Asp.net 如何从.net核心mvc服务生成API密钥?(在中间件中使用身份验证)

Asp.net 如何从.net核心mvc服务生成API密钥?(在中间件中使用身份验证),asp.net,asp.net-mvc,asp.net-core,Asp.net,Asp.net Mvc,Asp.net Core,我有一个.NET核心MVC rest服务,它通过验证密钥来限制对API的访问 它使用一个中间件函数来检查有效密钥的请求(在路由到api函数之前),如果无效则返回未经授权的响应 我的问题是如何生成密钥?由于所有请求都通过该中间件检查密钥是否有效,因此我需要一种生成密钥的方法 我知道有一个单独的身份服务器是很常见的,但我认为这对于我的情况来说太过分了,因为一个有效的密钥可以访问整个API。没有权限结构 我可以检查传入的请求,看是否有迹象表明用户正在尝试使用用户名+密码进行身份验证并返回密钥,但这似乎

我有一个.NET核心MVC rest服务,它通过验证密钥来限制对API的访问

它使用一个中间件函数来检查有效密钥的请求(在路由到api函数之前),如果无效则返回未经授权的响应

我的问题是如何生成密钥?由于所有请求都通过该中间件检查密钥是否有效,因此我需要一种生成密钥的方法

我知道有一个单独的身份服务器是很常见的,但我认为这对于我的情况来说太过分了,因为一个有效的密钥可以访问整个API。没有权限结构

我可以检查传入的请求,看是否有迹象表明用户正在尝试使用用户名+密码进行身份验证并返回密钥,但这似乎不正确

有没有一种方法可以允许单个服务调用跳过中间件?

中间件功能:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

namespace PatrolLiveRestService.Middleware
{
    public class KeyValidatorMiddleware
    {

        private readonly RequestDelegate _next;
        //private IContactsRepository ContactsRepo { get; set; }

        public KeyValidatorMiddleware(RequestDelegate next)//, IContactsRepository _repo)
        {
            _next = next;
            //ContactsRepo = _repo;
        }

        public async Task Invoke(HttpContext context)
        {
            if (!context.Request.Headers.Keys.Contains("api-key"))
            {
                context.Response.StatusCode = 400; //Bad Request                
                await context.Response.WriteAsync("API Key is missing");
                return;
            }
            if (!context.Request.Headers.Keys.Contains("device-id"))
            {
                context.Response.StatusCode = 400; //Bad Request                
                await context.Response.WriteAsync("Device ID is missing");
                return;
            }

            string apiKey = context.Request.Headers["api-key"];
            int deviceId;
            if (!int.TryParse(context.Request.Headers["device-id"], out deviceId))
            {
                context.Response.StatusCode = 401; //UnAuthorized
                await context.Response.WriteAsync("Invalid Device ID");
                return;
            }

            if (!Common.ServiceCommon.IsKeyValid(apiKey, deviceId))
            {
                context.Response.StatusCode = 401; //UnAuthorized
                await context.Response.WriteAsync("Invalid API Key");
                return;
            }

            await _next.Invoke(context);
        }


    }

    #region ExtensionMethod
    public static class UserKeyValidatorsExtension
    {
        public static IApplicationBuilder ApplyUserKeyValidation(this IApplicationBuilder app)
        {
            app.UseMiddleware<KeyValidatorMiddleware>();
            return app;
        }
    }
    #endregion

}

我认为有三种方法:

  • 检查
    keyvalidator中间件中的context.Request.Url
    (例如,对于路径
    /不需要api密钥端点
    不要强制存在api密钥头
  • 更改
    KeyValidatorMiddleware
    -不要拒绝没有api密钥头的请求,只需将
    context.User
    属性设置为
    ClaimsPrincipal
    ,声明为有效传入请求的设备id和api密钥,并通过
    [Authorize]在控制器级别筛选出没有有效授权的请求
    属性
  • 不要将其实现为中间件,而是将其实现为操作过滤器

只有当
context.User
存在时,才会调用具有
[Authorize]
属性的函数?@JamesWierzba-或多或少;实际上它类似于context.User.Identity.IsAuthenticated==true…好的,我倾向于选项3(操作过滤器).我尝试了选项2,但似乎我无法控制调用服务函数时会发生什么,并且没有授权用户(它返回泛型500错误,而我希望返回特定代码和消息)我已经实现了一个操作筛选器,但我不知道在身份验证失败时如何使管道短路。您知道如何从筛选器返回响应吗?我找不到任何文档
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
    app.ApplyUserKeyValidation();
...
}