C# .NET核心API密钥和;身份整合

C# .NET核心API密钥和;身份整合,c#,asp.net-core,asp.net-identity,asp.net-core-webapi,C#,Asp.net Core,Asp.net Identity,Asp.net Core Webapi,目前正在使用.NET CORE 3.1和Identity构建一个API,以在其中管理我们的身份验证/授权。我们希望使用生成的API键,而不是需要刷新的短生命令牌(这不适合我们的用例场景) 我们想要做的是为用户/第三方提供生成API密钥的选项,并允许他们将身份角色分配给API密钥,而不是用户。这样,我们仍然可以使用[Authorize]属性来授予/限制他们对特定端点的访问 我们有一个用户表,用于处理核心应用程序本身内的身份验证/授权,还有一个存储生成的API密钥的表。一个用户可以生成多个API密钥

目前正在使用.NET CORE 3.1和Identity构建一个API,以在其中管理我们的身份验证/授权。我们希望使用生成的API键,而不是需要刷新的短生命令牌(这不适合我们的用例场景)

我们想要做的是为用户/第三方提供生成API密钥的选项,并允许他们将身份角色分配给API密钥,而不是用户。这样,我们仍然可以使用[Authorize]属性来授予/限制他们对特定端点的访问

我们有一个用户表,用于处理核心应用程序本身内的身份验证/授权,还有一个存储生成的API密钥的表。一个用户可以生成多个API密钥(例如,一个具有对端点的只读权限,另一个具有写入权限)。我们只需要将API密钥链接到身份角色,并在通过请求头传入所述API密钥时使用[Authorize]属性


有没有人对如何实现这一目标有什么想法/建议?或者,对于这是否是一个坏主意以及如何做得更好,有什么建议吗?任何建议都值得赞赏。

您可以覆盖许多JWT示例所使用的[Authorize]属性,但将JWT弯曲到它不打算做的事情,这是一个有点粗糙的解决方案

我的建议是将API密钥添加为API端点的请求参数,并将任何数据有效负载放在请求主体中。e、 g.
/api/someendpoint/?apiKey={some\u api\u key}

然后,您可以创建一个BaseController类,供API控制器从中继承,以便在需要时对密钥执行验证检查

这不允许您根据需要使用[Authorize]属性,但它可以让您在短期内启动并运行。一旦主要概念发挥作用,创建自定义[AuthorizeApiKey]属性就不远了,但这将是您需要研究的问题

下面是一些示例代码

BaseController.cs

public class BaseController : Controller
{
  ...
  // Returns true if key is valid, returns false if invalid
  protected async Task<bool> ValidateApiKey(string apiKey)
  {
    var result = false;

    // Logic to check API key...

    return result;
  }

  ...
}
[Area("API")]
[Route("api/[controller]")]
[ApiController]
public class SomeApiController : BaseController
{
   [HttpGet]
   public async Task<IActionResult> GetWidgets(string apiKey)
   {
      var authorized = ValidateApiKey(apiKey);
      
      // If key is invalid, return a relevant response
      if(!authorized) return Unauthorized();

      // Otherwise, process the request and return the expected result
      var widgets = _SomeWidgetService.GetWidgets();

      return Created(widgets);
   }


   [HttpPost]
   public async Task<IActionResult> CreateWidget(string apiKey, [FromBody] WidgetClass widget)
   {
      var authorized = ValidateApiKey(apiKey);
      
      // If key is invalid, return a relevant response
      if(!authorized) return Unauthorized();

      // Otherwise process the rest of the action
      var result = (bool)_SomeWidgetService.CreateWidget(widget);

      if(result)
         return Created(); 
      else
         return BadRequest();
   }
}
公共类BaseController:控制器
{
...
//如果密钥有效,则返回true;如果无效,则返回false
受保护的异步任务ValidatePikey(字符串apiKey)
{
var结果=假;
//检查API密钥的逻辑。。。
返回结果;
}
...
}
SomeApiController.cs

public class BaseController : Controller
{
  ...
  // Returns true if key is valid, returns false if invalid
  protected async Task<bool> ValidateApiKey(string apiKey)
  {
    var result = false;

    // Logic to check API key...

    return result;
  }

  ...
}
[Area("API")]
[Route("api/[controller]")]
[ApiController]
public class SomeApiController : BaseController
{
   [HttpGet]
   public async Task<IActionResult> GetWidgets(string apiKey)
   {
      var authorized = ValidateApiKey(apiKey);
      
      // If key is invalid, return a relevant response
      if(!authorized) return Unauthorized();

      // Otherwise, process the request and return the expected result
      var widgets = _SomeWidgetService.GetWidgets();

      return Created(widgets);
   }


   [HttpPost]
   public async Task<IActionResult> CreateWidget(string apiKey, [FromBody] WidgetClass widget)
   {
      var authorized = ValidateApiKey(apiKey);
      
      // If key is invalid, return a relevant response
      if(!authorized) return Unauthorized();

      // Otherwise process the rest of the action
      var result = (bool)_SomeWidgetService.CreateWidget(widget);

      if(result)
         return Created(); 
      else
         return BadRequest();
   }
}
[区域(“API”)]
[路由(“api/[控制器]”)]
[ApiController]
公共类SomeApicController:BaseController
{
[HttpGet]
公共异步任务GetWidgets(字符串apiKey)
{
var授权=ValidateAppikey(apiKey);
//如果密钥无效,则返回相关响应
如果(!authorized)返回Unauthorized();
//否则,处理请求并返回预期结果
var widgets=_SomeWidgetService.GetWidgets();
创建的返回(小部件);
}
[HttpPost]
公共异步任务CreateWidget(字符串apiKey,[FromBody]WidgetClass小部件)
{
var授权=ValidateAppikey(apiKey);
//如果密钥无效,则返回相关响应
如果(!authorized)返回Unauthorized();
//否则,处理其余的操作
var result=(bool)\u SomeWidgetService.CreateWidget(widget);
如果(结果)
返回已创建();
其他的
返回请求();
}
}

为什么不将TLS与证书一起使用?您好,您可以指定授权的默认策略,这可以让您将其设置为自己的自定义策略。我写了一个关于这个问题的答案,你可能会发现它很有用@jdweng我想你误解了这个问题。TLS是一种传输协议,与API身份验证/授权无关Read Wiki:同意Kevin的说法,您可以使用自定义策略或自定义授权属性来实现授权。更多详细信息,请查看以下链接:,和。