实现 JWT 身份验证 Azure Function 3.x - 使用 JWT 令牌获取当前用户的声明
Posted
技术标签:
【中文标题】实现 JWT 身份验证 Azure Function 3.x - 使用 JWT 令牌获取当前用户的声明【英文标题】:Implementing JWT authentication Azure Function 3.x - Get Current User's Claims Using JWT token 【发布时间】: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()));
【问题讨论】:
您还有其他顾虑吗?如果您没有其他顾虑,您能否接受它作为答案(meta.stackexchange.com/questions/5234/…)? 【参考方案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
文件中添加以下设置。更多详情请参考here和here
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
</PropertyGroup>
.....
</Project>
【讨论】:
以上是关于实现 JWT 身份验证 Azure Function 3.x - 使用 JWT 令牌获取当前用户的声明的主要内容,如果未能解决你的问题,请参考以下文章
Asp Core:Azure Ad Auth + 自定义 JWT + 自定义身份存储
构建 VSTS 扩展 azure webapp 身份验证 JWT 令牌验证失败
使用 Azure API 管理从身份提供者缓存 JWKS 以验证 JWT