代码之家  ›  专栏  ›  技术社区  ›  robusta

如何在保护asp时从Azure AD获取用户。具有JWT令牌的net core web api

  •  0
  • robusta  · 技术社区  · 8 年前

    这是我的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 回复  |  直到 8 年前
        1
  •  2
  •   juunas    8 年前

    你的React客户端应该重定向到Azure广告登录页面,然后获取JWT 来自Azure广告

    https://blog.mastykarz.nl/building-office-365-web-applications-react/

    Azure AD v2在ASP中的使用示例。NET MVC核心API: https://contos.io/protecting-a-net-core-api-with-azure-active-directory-59bbcd5b3429