简体   繁体   English

.NET 核心 API 密钥和身份集成

[英].NET Core API keys & Identity integration

Currently building an API using .NET CORE 3.1 and Identity to manage our authentication / authorization within it.目前正在使用 .NET CORE 3.1 和 Identity 构建 API,以管理我们在其中的身份验证/授权。 We're looking to use generated API keys rather than short life tokens that need to be refreshed (it doesn't suit our use case scenario).我们希望使用生成的 API 密钥,而不是需要刷新的短寿命令牌(它不适合我们的用例场景)。

What we want to do is provide the option for users/third parties to generate API keys and allow them to assign Identity Roles to the API key rather than a user.我们要做的是为用户/第三方提供生成 API 密钥的选项,并允许他们将身份角色分配给 API 密钥而不是用户。 That way we could still use the [Authorize] attribute to grant / restrict their access to particular endpoints.这样我们仍然可以使用 [Authorize] 属性来授予/限制他们对特定端点的访问。

We have a Users table that handles authentication / authorization within the core application itself and have a table that stores the generated API keys.我们有一个用户表来处理核心应用程序本身的身份验证/授权,并有一个表来存储生成的 API 密钥。 One user can generate multiple API keys (one with read only permission to endpoints and one with write, for example).一个用户可以生成多个 API 密钥(例如,一个对端点具有只读权限,一个具有写入权限)。 We just need to link the API keys to Identity Roles and utilise the [Authorize] attribute when said API key is passed in via the Request Header.我们只需要将 API 密钥链接到身份角色,并在通过请求 Header 传入所述 API 密钥时使用 [Authorize] 属性。

Does anybody have any ideas / advice about how to make this work?有人对如何使这项工作有任何想法/建议吗? Or any advice as to whether this is a bad idea and how it could be done better?或者关于这是否是一个坏主意以及如何做得更好的任何建议? Any advice appreciated.任何建议表示赞赏。

You could override the [Authorize] attribute that many of the JWT examples use, but its a bit of a hacky solution to bend JWT to do something it wasn't designed to do.您可以覆盖许多 JWT 示例使用的 [Authorize] 属性,但它有点不合时宜地弯曲 JWT 来做一些它不打算做的事情。

My suggestion would be to add the API key as a request parameter for your API endpoints and put any data payloads in the body of the request.我的建议是将 API 密钥添加为您的 API 端点的请求参数,并将任何数据有效负载放入请求的正文中。 eg /api/someendpoint/?apiKey={some_api_key}例如/api/someendpoint/?apiKey={some_api_key}

You could then create a BaseController class for you API controllers to inherit from to perform a validation check on the key wherever it's needed.然后,您可以为您的 API 控制器创建一个 BaseController class 来继承,以便在需要时对密钥执行验证检查。

This won't allow you to use the [Authorize] attribute as you wanted, but it would get you up and running for the short term.这将不允许您根据需要使用 [Authorize] 属性,但它会让您在短期内启动并运行。 Creating a custom [AuthorizeApiKey] attribute wouldn't be far off once you've got the main concept working, but that would be something for you to investigate.一旦您掌握了主要概念,创建自定义 [AuthorizeApiKey] 属性就不会太远了,但这需要您进行调查。

Here's some example code.这是一些示例代码。

BaseController.cs基本控制器.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;
  }

  ...
}

SomeApiController.cs SomeApiController.cs

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

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM