【问题标题】:Using JSON Web Tokens (JWT) with Azure Functions (WITHOUT using Active Directory)将 JSON Web 令牌 (JWT) 与 Azure Functions 结合使用(不使用 Active Directory)
【发布时间】:2018-08-16 04:26:21
【问题描述】:

我确信已经有人这样做了,但是我还没有找到任何关于 Microsoft 实现 JWT 的文档。 Microsoft 为其 JWT 库提供的官方文档基本上是一个空白页面,请参阅:

https://docs.microsoft.com/en-us/dotnet/framework/security/json-web-token-handler-api-reference

所以,这就是我(我相信还有很多其他人)想要完成的事情:

定义: 用户 ID = 用于登录系统的用户名或电子邮件地址。

身份验证:

  1. 用户登录。用户填写 Web 表单,系统将(通过 HTTPS POST)用户 ID 和密码(散列)发送到服务器,以验证/验证用户。

  2. 服务器对用户进行身份验证。根据保存在数据库中的值检查用户 ID 和密码,如果无效,则向调用者返回无效的登录响应。

  3. 创建 JWT 令牌 - ????没有可用的文档!

  4. 将 JWT 令牌返回给调用者 - ???? - 我假设在标题中?通过 JSON,不确定 - 再次 - 没有文档。

鉴于下面的代码,谁能提供第 3 步和第 4 步的代码示例?

  [FunctionName( "authenticate" )]
  public static async Task<HttpResponseMessage> Run( [HttpTrigger( AuthorizationLevel.Anonymous, "get", "post", Route = null )]HttpRequestMessage req, TraceWriter log )
  {

   // Step 1 - Get user ID and password from POST data

   /*
   * Step 2 - Verify user ID and password (compare against DB values)
   * If user ID or password is not valid, return Invalid User response
   */

   // Step 3 - Create JWT token - ????

   // Step 4 - Return JWT token - ????

  }

授权

假设用户已通过身份验证并且现在拥有 JWT 令牌(我假设 JWT 令牌保存在用户会话中;如果有人想提供更多信息,请提供):

  1. 向 Azure 函数发出 POST 请求以执行某些操作(例如获取用户的出生日期)。上面获得的 JWT 令牌与函数所需的任何其他数据一起加载(从 POST 数据或标头 - 这有关系吗?)。

  2. JWT 令牌已验证 - ????没有可用的文档!

  3. 如果 JWT 令牌无效,则函数返回 BadRequest 响应。

  4. 如果 JWT 令牌有效,则函数使用传递给它的数据来处理并发出响应。

鉴于下面的代码,任何人都可以提供第 1 步和第 2 步的代码示例吗?

  [FunctionName( "do_something" )]
  public static async Task<HttpResponseMessage> Run( [HttpTrigger( AuthorizationLevel.Anonymous, "get", "post", Route = null )]HttpRequestMessage req, TraceWriter log )
  {

   // Step 1 - Get JWT token (from POST data or headers?)

   // Step 2 - Validate the JWT token - ???

   // Step 3 - If JWT token is not valid, return BadRequest response

   // Step 4 - Process the request and return data as JSON

  }

任何和所有信息都会真正帮助我们这些人(我)了解如何将 JWT 与 Azure(匿名)函数一起使用,以构建“安全”的 REST API。

提前致谢。

【问题讨论】:

    标签: azure jwt azure-functions


    【解决方案1】:

    基本上是在 ASP.NET Core 之上构建的 Azure Functions。通过制作一些依赖注入技巧,您可以添加自己的身份验证和基于策略的授权。我使用 JWT 身份验证创建 demo solution 只是为了好玩,请注意在生产中使用它。

    【讨论】:

      【解决方案2】:

      我为 JWT 令牌验证创建了一个 Azure Functions 输入绑定。您可以将其用作带有 [JwtBinding] 属性的额外参数。请参阅 https://hexmaster.nl/posts/az-func-jwt-validator-binding/ 了解源代码和 NuGet 包信息。

      【讨论】:

        【解决方案3】:

        试试这个:https://liftcodeplay.com/2017/11/25/validating-auth0-jwt-tokens-in-azure-functions-aka-how-to-use-auth0-with-azure-functions/ 我使用本指南成功地使它工作。由于 nuget 版本,需要一段时间。

        正确遵循该指南并使用以下 nuget 版本

        IdentityModel.Protocols (2.1.4)
        IdentityModel.Protocols.OpenIdConenct (2.1.4)
        IdentityModel.Tokens.Jwt (5.1.4)
        

        哦,指南告诉您将 AUDIENCE 写为您的 api 链接,不要。你会得到未经授权的错误。只需写下您的 api 名称,例如我的api

        如果您在运行该函数时收到有关 System.http.formatting 未加载的错误,请尝试重新安装 NET.Sdk.Functions 并忽略有关使用 .NETFramework 恢复 AspNet.WebApi.Client 的警告。并重新启动 Visual Studio。

        【讨论】:

          【解决方案4】:

          任何和所有信息都会真正帮助我们这些人(我)了解如何将 JWT 与 Azure(匿名)函数一起使用,以构建“安全”的 REST API。

          据我了解,您可以在 azure 函数代码中使用相关库来生成/验证 JWT 令牌。这里有一些教程,你可以参考:

          Create and Consume JWT Tokens in C#

          Jwt.Net, a JWT (JSON Web Token) implementation for .NET

          JWT Authentication for Asp.Net Web Api

          此外,您可以利用App Service Authentication / Authorization 来配置函数应用级别的身份验证/授权。您可以转到您的功能应用程序设置,单击平台功能选项卡下的“网络 > 身份验证/授权”。启用应用服务身份验证并选择允许匿名请求(无操作),如下所示:

          您可以创建一个具有匿名访问权限的 HttpTrigger 函数来记录用户,并在用户存在时返回 JWT 令牌。对于受保护的 REST API,您可以按照以下代码示例进行操作:

          if(System.Security.Claims.ClaimsPrincipal.Current.Identity.IsAuthenticated)
          {
             //TODO: retrieve the username claim
             return req.CreateResponse(HttpStatusCode.OK,(System.Security.Claims.ClaimsPrincipal.Current.Identity as ClaimsIdentity).Claims.Select(c => new { key = c.Type, value = c.Value }),"application/json");
          }
          else
          {
              return req.CreateResponse(HttpStatusCode.Unauthorized,"Access Denied!"); 
          }
          

          要生成用于应用服务身份验证的 JWT 令牌,您可以按照阿德里安霍尔关于 Custom Authentication 的书中的 How to: Use custom authentication for your application 和自定义 API 控制器 CustomAuthController 下的代码来创建 JWT 令牌。

          更新:

          对于应用服务身份验证下的自定义身份验证方法,我只想让 op 利用 EasyAuth 提供的身份验证/授权。我对这种方法做了一些测试,发现它可以在我这边工作。 Op 可以将用户名和密码发送给 HttpTrigger 进行身份验证,然后 HttpTrigger 后端需要验证用户信息,并使用 Microsoft.Azure.Mobile.Server.Login 包向客户端颁发 App Service Authentication 令牌,然后客户端可以从 @ 检索令牌987654332@ 财产。针对受保护 API 的后续请求可能如下所示:

          https://<your-funapp-name>.azurewebsites.net/api/<httpTrigger-functionName>
          Header: x-zumo-auth:<AuthenticationToken>
          

          注意:

          对于这种方法,相关的 HttpTrigger 函数需要允许匿名访问,并且应用服务身份验证也需要选择允许匿名请求(无操作)。否则,应用服务身份验证和功能级别身份验证都会验证请求。对于受保护的API,op需要手动添加System.Security.Claims.ClaimsPrincipal.Current.Identity.IsAuthenticated检查。

          【讨论】:

          • 这很有帮助,所以 +1,但关于自定义身份验证的部分可能对 OP 的问题没有帮助。
          • 对于自定义身份验证方法,我做了一些测试,发现它可以工作,所以我用解释更新了我的答案。
          • 通过匿名使用“应用服务身份验证”可以获得什么?这不就等于根本没有任何身份验证吗?
          【解决方案5】:

          您所描述的是您应该能够通过做一些研究自己做的事情。解决您的具体问题:

          创建 JWT 令牌 - ????没有可用的文档!

          Bruce 为您提供的链接提供了一个很好的示例来说明如何创建 JWT:https://www.codeproject.com/Tips/1208535/Create-And-Consume-JWT-Tokens-in-csharp

          将 JWT 令牌返回给调用者 - ???? - 我假设在标题中?通过 JSON,不确定 - 再次 - 没有文档。

          没有文档,因为您基本上是在发明自己的协议。这意味着您如何做到这一点完全取决于您和您的应用程序要求。如果它是登录操作,则将其作为 HTTP 响应负载的一部分返回可能是有意义的。只需确保您使用的是 HTTPS,以便令牌通过网络受到保护。

          向 Azure 函数发出 POST 请求以执行某些操作(例如获取用户的出生日期)。上面获得的 JWT 令牌与函数所需的任何其他数据一起加载(从 POST 数据或标头 - 重要吗?)。

          再次,您如何发送令牌完全取决于您。大多数平台使用 HTTP Authorization 请求标头,但如果您不想这样做,则不必这样做。

          JWT 令牌已验证 - ????没有可用的文档!

          使用JwtSecurityTokenHandlerValidateToken 方法(有关如何获取JwtSecurityTokenHandler,请参阅上一个链接)。此处的文档:https://msdn.microsoft.com/en-us/library/dn451155(v=vs.114).aspx

          【讨论】:

          • 克里斯,我碰巧在寻找相同的信息,我同意微软文档缺乏的 OP。并不是所有的用户都可以是认证协议方面的专家;这里有一个假设,即在身份验证方面重新发明轮子是没有意义的,它应该“正常工作”。此外,由于库在去年已经更新,目前社区中的文档非常分散,但在使用 Functions 的 authn/authz 方面仍然非常缺乏。
          猜你喜欢
          • 1970-01-01
          • 2017-06-15
          • 2013-12-27
          • 2020-11-17
          • 1970-01-01
          • 2018-03-24
          • 2020-01-03
          • 2018-03-10
          • 2021-06-02
          相关资源
          最近更新 更多