我在React JS中擁有.net核心Web API和SPA客戶端。我想允許用戶使用在Azure AD中註冊的電子郵件從客戶端登錄,並使用JWT令牌保護我的web api。我嘗試使用簡單的硬編碼用戶名和密碼生成令牌,但我不知道如何從Azure AD獲取用戶並生成JWT令牌。如何在使用JWT令牌保護asp.net核心Web API時從Azure AD獲取用戶
這裏是我的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);
}
}
人有一個想法如何實現這一點?
我不明白這一點。 JWT令牌如何通過客戶端的簡單重定向從AzureAD生成? –
請參閱此處的流程圖瞭解其工作原理:https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-scenarios#single-page-application-溫泉。如果您的API和SPA前端在Azure AD中實際上是同一個應用程序,那麼您可以在他們提到的地方進行操作,然後只發送ID令牌。否則,您可以使用Adal.js爲其他API獲取額外的訪問令牌。 – juunas
還有一個使用Angular的示例應用程序:https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp – juunas