【问题标题】:Implementing JWT authentication Azure Function 3.x - Get Current User's Claims Using JWT token实现 JWT 身份验证 Azure Function 3.x - 使用 JWT 令牌获取当前用户的声明
【发布时间】:2020-11-29 23:01:10
【问题描述】:

我正在使用 Azure 函数将新开发堆栈上的 dontcore Web API 转换为无服务器。

我认为我的应用程序应该使用 Identity 来存储用户凭据和其他详细信息。他应该通过身份数据库进行身份验证并使用 JWT 令牌生成。

我正在尝试获取一些示例,这些示例可能有助于了解如何在 Azure 函数中实现 JWT。

JWT 令牌生成过程

     public UserResponce AuthendicateUser(string username, string password)
        {
            bool valid_user= ValidateUser(username,password);
            if (vlaid_user)
            {

                // authentication successful so generate jwt token
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes(_jwtIssuerOptions.Value.JwtKey);
                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(new Claim[]
                    {
                    new Claim(ClaimTypes.Name, "1"),
                    new Claim(ClaimTypes.GivenName, username),
                    new Claim(ClaimTypes.Role, UserRoleEnum.superadmin.ToString()),
                    new Claim("hospitalid", "1")
                    }),
                    Expires = DateTime.UtcNow.AddMinutes(_jwtIssuerOptions.Value.JwtExpireMinutes),
                    IssuedAt = DateTime.UtcNow,
                    NotBefore = DateTime.UtcNow,
                    Audience = _jwtIssuerOptions.Value.JwtAuidence,
                    Issuer = _jwtIssuerOptions.Value.JwtIssuer,
                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
                };
                var token = tokenHandler.CreateToken(tokenDescriptor);
                string newJwttoken = tokenHandler.WriteToken(token);

                return new UserResponce
                {

                    //HospitalId = user.HospitalId.Value,
                    Token = newJwttoken,
                    UserId = 1,
                    UserName = username,
                    Expires = DateTime.UtcNow.AddMinutes(_jwtIssuerOptions.Value.JwtExpireMinutes),
                };
            }
            else
            {
                return null;
            }

        }

使用像 Bellow 代码这样的函数,其中用户、身份值获取 Nulls

        var user = req.HttpContext.User;
        var identity = claimsPrincipal.Identity;

功能代码

        [FunctionName("Get_User")]
        public async Task<IActionResult> GetUser(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = Globals.UserRoute+"/getuser")] HttpRequest req, ILogger log, ClaimsPrincipal claimsPrincipal)
        {

            log.LogInformation("C# HTTP trigger function processed a request started");
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            AuthendicateModel data = JsonConvert.DeserializeObject<AuthendicateModel>(requestBody);
            var user = req.HttpContext.User;
            var identity = claimsPrincipal.Identity;
            var details = _userService.Username();
            log.LogInformation("C# HTTP trigger function processed a request.");
            return new OkObjectResult(new ApiResponse(HttpStatusCode.OK, details, ResponseMessageEnum.Success.ToString()));

        }

【问题讨论】:

标签: azure .net-core jwt azure-functions claims-based-identity


【解决方案1】:

无需验证。就用这个包DarkLoop.Azure.Functions.Authorize

在你的启动类中初始化认证:

builder.Services
    .AddFunctionsAuthentication();
    .AddJwtBearer(options => 
     {
        //your JWT configuration here just like in ASPNET Core
     });

builder.Services.AddFunctionsAuthorization();

那么您需要做的就是用FunctionAuthorizeAttribute 装饰您的函数或函数类,您就可以拥有与 ASPNET WebAPI 中相同的精细控制:

    [FunctionAuthorize]
    [FunctionName("Get_User")]
    public async Task<IActionResult> GetUser(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = Globals.UserRoute+"/getuser")] HttpRequest req, ILogger log)
    {

        log.LogInformation("C# HTTP trigger function processed a request started");
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        AuthendicateModel data = JsonConvert.DeserializeObject<AuthendicateModel>(requestBody);
        var user = req.HttpContext.User;
        var identity = user.Identity;
        var claims = user.Claims;
        var details = _userService.Username();
        log.LogInformation("C# HTTP trigger function processed a request.");
        return new OkObjectResult(new ApiResponse(HttpStatusCode.OK, details, ResponseMessageEnum.Success.ToString()));

    }

【讨论】:

    【解决方案2】:

    如果你想在 Azure 函数中验证你的 jwt 令牌,你可以使用 sdk System.IdentityModel.Tokens.Jwt 来实现它。更多详情请参考here

    例如

    var authorizationHeader = req.Headers?["Authorization"];
                string[] parts = authorizationHeader?.ToString().Split(null) ?? new string[0];
                string token = string.Empty;
                if (parts.Length == 2 && parts[0].Equals("Bearer"))
                    token = parts[1];
                var tokenHandler = new JwtSecurityTokenHandler();
                
                var key = Encoding.ASCII.GetBytes("your jwt key vaule");
                // Validate Token and read claims
    
                // defile the validation Parameters according to your need
                var validationParameters = new TokenValidationParameters()
                {
                    RequireExpirationTime = true,
                    IssuerSigningKey= new  SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
    
                SecurityToken securityToken;
                try {
                    // Validate Token
                    ClaimsPrincipal principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);
                    var name = principal.Identity.Name;
                    log.LogInformation($"the name is {name}");
                    // read claims
                    foreach (var claim in principal.Claims) {
                        // process the claim
                    }
                } catch (Exception ex) {
                    
                    // process exception
                     
                
                }
    

    此外,如果您在运行该函数时遇到关于Could not load file or assembly System.IdentityModel.Tokens.Jwt 的问题,请在您的.csproj 文件中添加以下设置。更多详情请参考herehere

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <AzureFunctionsVersion>v3</AzureFunctionsVersion>
         <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
      </PropertyGroup>
      .....
    </Project>
    

    【讨论】:

      猜你喜欢
      • 2019-06-17
      • 2017-12-10
      • 1970-01-01
      • 2017-09-09
      • 2021-10-12
      • 2019-01-22
      • 2015-01-21
      • 2020-11-22
      • 2018-05-10
      相关资源
      最近更新 更多