aboutsummaryrefslogtreecommitdiff
path: root/Timeline/Services/JwtService.cs
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2019-02-14 23:05:04 +0800
committercrupest <crupest@outlook.com>2019-02-14 23:05:04 +0800
commit3c140656ebe6ed34dda9356a01dbff205651e641 (patch)
tree8b8ca7331c9510b897042737a5cbbc0f77b1b736 /Timeline/Services/JwtService.cs
parentde90f0413553a23f8ebba1343c6e96c63e0c9748 (diff)
downloadtimeline-3c140656ebe6ed34dda9356a01dbff205651e641.tar.gz
timeline-3c140656ebe6ed34dda9356a01dbff205651e641.tar.bz2
timeline-3c140656ebe6ed34dda9356a01dbff205651e641.zip
Develop user token interface.
Diffstat (limited to 'Timeline/Services/JwtService.cs')
-rw-r--r--Timeline/Services/JwtService.cs74
1 files changed, 70 insertions, 4 deletions
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
{
/// <summary>
@@ -21,16 +26,34 @@ namespace Timeline.Services
/// <param name="user">The user to generate token.</param>
/// <returns>The generated token or null if <paramref name="user"/> is null.</returns>
string GenerateJwtToken(User user);
+
+ /// <summary>
+ /// Validate a JWT token.
+ /// Return null is <paramref name="token"/> is null.
+ /// If token is invalid, return a <see cref="TokenValidationResult"/> with
+ /// <see cref="TokenValidationResult.IsValid"/> set to false and
+ /// <see cref="TokenValidationResult.UserInfo"/> set to null.
+ /// If token is valid, return a <see cref="TokenValidationResult"/> with
+ /// <see cref="TokenValidationResult.IsValid"/> set to true and
+ /// <see cref="TokenValidationResult.UserInfo"/> filled with the user info
+ /// in the token.
+ /// </summary>
+ /// <param name="token">The token string to validate.</param>
+ /// <returns>Null if <paramref name="token"/> is null. Or the result.</returns>
+ TokenValidationResult ValidateJwtToken(string token);
+
}
public class JwtService : IJwtService
{
private readonly IOptionsMonitor<JwtConfig> _jwtConfig;
private readonly JwtSecurityTokenHandler _tokenHandler = new JwtSecurityTokenHandler();
+ private readonly ILogger<JwtService> _logger;
- public JwtService(IOptionsMonitor<JwtConfig> jwtConfig)
+ public JwtService(IOptionsMonitor<JwtConfig> jwtConfig, ILogger<JwtService> 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 };
+ }
+ }
}
}