From 3c140656ebe6ed34dda9356a01dbff205651e641 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 14 Feb 2019 23:05:04 +0800 Subject: Develop user token interface. --- Timeline/Services/JwtService.cs | 74 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) (limited to 'Timeline/Services/JwtService.cs') diff --git a/Timeline/Services/JwtService.cs b/Timeline/Services/JwtService.cs index 1b465dd9..a01f3f2b 100644 --- a/Timeline/Services/JwtService.cs +++ b/Timeline/Services/JwtService.cs @@ -1,17 +1,22 @@ -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System; -using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Text; -using System.Threading.Tasks; using Timeline.Configs; using Timeline.Entities; namespace Timeline.Services { + public class TokenValidationResult + { + public bool IsValid { get; set; } + public UserInfo UserInfo { get; set; } + } + public interface IJwtService { /// @@ -21,16 +26,34 @@ namespace Timeline.Services /// The user to generate token. /// The generated token or null if is null. string GenerateJwtToken(User user); + + /// + /// Validate a JWT token. + /// Return null is is null. + /// If token is invalid, return a with + /// set to false and + /// set to null. + /// If token is valid, return a with + /// set to true and + /// filled with the user info + /// in the token. + /// + /// The token string to validate. + /// Null if is null. Or the result. + TokenValidationResult ValidateJwtToken(string token); + } public class JwtService : IJwtService { private readonly IOptionsMonitor _jwtConfig; private readonly JwtSecurityTokenHandler _tokenHandler = new JwtSecurityTokenHandler(); + private readonly ILogger _logger; - public JwtService(IOptionsMonitor jwtConfig) + public JwtService(IOptionsMonitor jwtConfig, ILogger logger) { _jwtConfig = jwtConfig; + _logger = logger; } public string GenerateJwtToken(User user) @@ -42,6 +65,7 @@ namespace Timeline.Services var identity = new ClaimsIdentity(); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); + identity.AddClaim(new Claim(identity.NameClaimType, user.Username)); identity.AddClaims(user.Roles.Select(role => new Claim(identity.RoleClaimType, role))); var tokenDescriptor = new SecurityTokenDescriptor() @@ -60,5 +84,47 @@ namespace Timeline.Services return tokenString; } + + + public TokenValidationResult ValidateJwtToken(string token) + { + if (token == null) + return null; + + var config = _jwtConfig.CurrentValue; + + try + { + var principal = _tokenHandler.ValidateToken(token, new TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidateIssuerSigningKey = true, + ValidateLifetime = true, + ValidIssuer = config.Issuer, + ValidAudience = config.Audience, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config.SigningKey)) + }, out SecurityToken validatedToken); + + var identity = principal.Identity as ClaimsIdentity; + + var userInfo = new UserInfo + { + Username = identity.FindAll(identity.NameClaimType).Select(claim => claim.Value).Single(), + Roles = identity.FindAll(identity.RoleClaimType).Select(claim => claim.Value).ToArray() + }; + + return new TokenValidationResult + { + IsValid = true, + UserInfo = userInfo + }; + } + catch (Exception e) + { + _logger.LogInformation(e, "Token validation failed! Token is {} .", token); + return new TokenValidationResult { IsValid = false }; + } + } } } -- cgit v1.2.3