使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户
Posted
技术标签:
【中文标题】使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户【英文标题】:How to get users from Azure AD when securing asp.net core web api with JWT token 【发布时间】:2017-12-01 14:57:21 【问题描述】:我在 React JS 中有一个 .net core web api 和 SPA 客户端。我想允许用户使用在 Azure AD 中注册的电子邮件从客户端登录,并使用 JWT 令牌保护我的 web api。我尝试使用简单的硬编码用户名和密码生成令牌,但我不知道如何从 Azure AD 获取用户并生成 JWT 令牌。
这是我的 JWTController:
[Route("api/[controller]")]
public class JwtController : Controller
private readonly JwtIssuerOptions _jwtOptions;
private readonly ILogger _logger;
private readonly JsonSerializerSettings _serializerSettings;
public JwtController(IOptions<JwtIssuerOptions> jwtOptions, ILoggerFactory loggerFactory)
_jwtOptions = jwtOptions.Value;
ThrowIfInvalidOptions(_jwtOptions);
_logger = loggerFactory.CreateLogger<JwtController>();
_serializerSettings = new JsonSerializerSettings
Formatting = Formatting.Indented
;
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Get([FromForm] string Username, string Password)
var applicationUser = new ApplicationUser();
applicationUser.UserName = Username;
applicationUser.Password = Password;
var identity = await GetClaimsIdentity(applicationUser);
if (identity == null)
_logger.LogInformation($"Invalid username(applicationUser.UserName) or password (applicationUser.Password)");
return BadRequest("Invalid credentials");
var claims = new[]
new Claim(JwtRegisteredClaimNames.Sub, applicationUser.UserName),
new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
new Claim(JwtRegisteredClaimNames.Iat,
ToUnixExpochDate(_jwtOptions.IssuedAt).ToString(),
ClaimValueTypes.Integer64),
identity.FindFirst("Disney")
;
//Create the JWT security token and encode it.
var jwt = new JwtSecurityToken(
issuer: _jwtOptions.Issuer,
audience: _jwtOptions.Audience,
claims:claims,
notBefore:_jwtOptions.NotBefore,
expires:_jwtOptions.Expiration,
signingCredentials:_jwtOptions.SigningCredentials);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
//Serialize and return the response.
var response = new
access_token = encodedJwt,
expires_in = (int)_jwtOptions.ValidFor.TotalSeconds
;
var json = JsonConvert.SerializeObject(response, _serializerSettings);
return new OkObjectResult(json);
private static void ThrowIfInvalidOptions(JwtIssuerOptions options)
if (options == null) throw new ArgumentNullException(nameof(options));
if (options.ValidFor <= TimeSpan.Zero)
throw new ArgumentException("Must be a non-zero TimeSpan.", nameof(JwtIssuerOptions.ValidFor));
if (options.SigningCredentials == null)
throw new ArgumentNullException(nameof(JwtIssuerOptions.SigningCredentials));
if (options.JtiGenerator == null)
throw new ArgumentNullException(nameof(JwtIssuerOptions.JtiGenerator));
private static long ToUnixExpochDate(DateTime date)
=> (long)Math.Round((date.ToUniversalTime() -
new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero))
.TotalSeconds);
private Task<ClaimsIdentity> GetClaimsIdentity(ApplicationUser user)
if (user.UserName == "mickey" && user.Password == "mouse")
return Task.FromResult(new ClaimsIdentity(
new GenericIdentity(user.UserName, "Token"),
new[]
new Claim("Disney", "mickey")
));
if (user.UserName == "notmickey" && user.Password == "mouse")
return Task.FromResult(new ClaimsIdentity(
new GenericIdentity(user.UserName, "Token"),
new Claim[] ));
return Task.FromResult<ClaimsIdentity>(null);
有人知道如何实现吗?
【问题讨论】:
【参考方案1】:我觉得你有点倒退了。
您的 React 客户端应该重定向到 Azure AD 登录页面,然后 从 Azure AD 获取 JWT 以调用您的 API。然后,您的 API 只需验证传入的令牌并为请求构建用户身份。 ASP.NET Core 中有现成的组件。
将 Adal.js 与 React 结合使用的一个示例:https://blog.mastykarz.nl/building-office-365-web-applications-react/
在 ASP.NET MVC Core API 中使用 Azure AD v2 的示例:https://contos.io/protecting-a-net-core-api-with-azure-active-directory-59bbcd5b3429
【讨论】:
我不明白。如何通过客户端的简单重定向从 AzureAD 生成 JWT 令牌? 请参阅此处的流程图以了解其工作原理:docs.microsoft.com/en-us/azure/active-directory/develop/…。如果您的 API 和 SPA 前端实际上是 Azure AD 中的同一应用程序,您可以按照他们在此处提到的操作,只需发送 ID 令牌。否则,您可以使用 Adal.js 为其他 API 获取额外的访问令牌。 还有一个使用 Angular 的示例应用程序:github.com/Azure-Samples/… 更多关于隐式授权流程:docs.microsoft.com/en-us/azure/active-directory/develop/…. 我去看看这个,谢谢你的帮助!以上是关于使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户的主要内容,如果未能解决你的问题,请参考以下文章
通过 Auth0 React 和 ASP.net 核心授权然后使用 JWT 令牌