使用带有Azure功能的JSON Web令牌(JWT)(不使用Active Directory)

时间:2018-03-07 22:54:04

标签: azure jwt azure-functions

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

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

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

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

AUTHENTICATION:

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

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

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

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

  5. 鉴于下面的代码,任何人都可以为步骤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 - ????
    
      }
    

    AUTHORIZATION

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

    1. 向Azure功能发出POST请求以执行某些操作(例如获取用户出生日期)。上面获得的JWT令牌(从POST数据或标题 - 它是否重要?)以及该函数所需的任何其他数据加载。

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

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

    4. 如果JWT令牌有效,该函数会使用传递给它的数据来处理和发出回复。

    5. 鉴于下面的代码,任何人都可以提供步骤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。

      提前致谢。

5 个答案:

答案 0 :(得分:9)

  

任何和所有信息都会真正帮助我们这些人(我)了解如何使用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配置功能应用级别身份验证/授权。您可以转到功能应用程序设置,单击平台功能选项卡下的“网络&gt;身份验证/授权”。启用应用服务身份验证并选择允许匿名请求(无操作),如下所示:

enter image description here

您可以使用匿名访问创建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令牌,您可以关注How to: Use custom authentication for your application以及adrian hall关于Custom Authentication的书中的自定义API控制器CustomAuthController下的代码来创建JWT令牌。

<强>更新

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

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

注意:

对于这种方法,相关的HttpTrigger函数需要允许匿名访问,而App Service Authentication也需要选择Allow Anonymous requests(no action)。否则,App Service身份验证和功能级别身份验证都将验证请求。对于受保护的API,op需要手动添加System.Security.Claims.ClaimsPrincipal.Current.Identity.IsAuthenticated检查。

答案 1 :(得分: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)

哦,指南告诉你把你的听众写成你的api链接,不要。您将收到未经授权的错误。只需写下你的api的名字,例如myapi

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

答案 2 :(得分:2)

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

  

创建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令牌已经过验证 - ????没有可用的文档!

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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