/// <summary> /// Generates a JWT token for the given user by id. /// </summary> /// <param name="userId">The id of the user to generate the access token for.</param> /// <param name="IsAdmin">Whether the user is an administrator or not.</param> /// <param name="tokenType">The type of the JWT token to generate.</param> /// <returns>The generated JWT token.</returns> private JwtSecurityToken GenerateJwtToken(int userId, bool IsAdmin, JwtTokenType tokenType) { var secretAsBytes = Encoding.UTF8.GetBytes(_appSettings.SylApi_Secret); var symmetricSecurityKey = new SymmetricSecurityKey(secretAsBytes); var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature); var claims = new List <Claim> { new Claim(ClaimTypes.Name, userId.ToString()), new Claim(ClaimTypes.Role, IsAdmin ? "Admin" : "User") }; var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = tokenType == JwtTokenType.AccessToken ? DateTime.UtcNow.AddMinutes(15) : DateTime.UtcNow.AddDays(14), SigningCredentials = signingCredentials, Issuer = "sylvre-webapi", Audience = tokenType == JwtTokenType.AccessToken ? "sylvre-webapi-client-access-token" : "sylvre-webapi-client-refresh-token" }; var tokenHandler = new JwtSecurityTokenHandler(); return(tokenHandler.CreateToken(tokenDescriptor) as JwtSecurityToken); }
/// <summary> /// 校验token是否正确 /// </summary> /// <param name="token"></param> /// <returns></returns> public virtual async Task <ClaimsPrincipal> ValidateTokenAsync(JwtTokenType jwtTokenType, string token, JwtOptions options = null) { if (options == null) { options = GetCurrentOptions(); } ClaimsPrincipal principal = _tokenHandler.ValidateToken(token, options.GetValidationParameters(), out _); string userId = null; if (options.EnabledSignalR) { userId = principal.Claims.FirstOrDefault(d => d.Type == nameof(TokenEntityBase.UserId)).Value; principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.NameIdentifier, userId) })); } if (options.Cache) { var clientType = principal.Claims.FirstOrDefault(d => d.Type == nameof(TokenEntityBase.ClientType)).Value; if (userId == null) { userId = principal.Claims.FirstOrDefault(d => d.Type == nameof(TokenEntityBase.UserId)).Value; } var tokenEntry = CacheEntryCollection.GetTokenEntry(jwtTokenType, clientType, userId, (int)options.AccessExpireMins * 60); var cacheToken = await _store.GetAsync <string>(tokenEntry); if (cacheToken.IsNullOrEmpty() || cacheToken != token) { throw new RyeException("Token is error"); } } return(principal); }
/// <summary> /// 获取Token缓存Key /// </summary> /// <param name="clientType"></param> /// <param name="userId"></param> /// <param name="expire"></param> /// <returns></returns> public static CacheOptionEntry GetTokenEntry(JwtTokenType tokenType, string clientType, string userId, int expire = 15 * 60) { return(new CacheOptionEntry { Key = $"Rye_{tokenType.ToString()}:{userId}:{clientType}", AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(expire) }); }
/// <summary> /// Initializes a new instance of the <see cref="JwtValue"/> class. /// </summary> /// <param name="value"></param> public JwtValue(byte[] value) { if (value == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); } Type = JwtTokenType.Utf8String; Value = value; }
/// <summary> /// Initializes a new instance of the <see cref="JwtValue"/> class. /// </summary> /// <param name="value"></param> public JwtValue(JwtObject value) { if (value == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); } Type = JwtTokenType.Object; Value = value; }
/// <summary> /// Builds the cookie options for the specified token type. /// </summary> /// <param name="tokenType">The type of the JWT token to generate the cookie options for.</param> /// <param name="isCookieDelete">Whether the cookie is being deleted or not.</param> /// <returns>The generated cookie options.</returns> private CookieOptions GenerateCookieOptions(JwtTokenType tokenType, bool isCookieDelete) { var cookieOptions = new CookieOptions { Path = "/", HttpOnly = true, Secure = true, IsEssential = true, Domain = _appSettings.SylApi_CookieDomain, SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax }; if (!isCookieDelete) { cookieOptions.Expires = tokenType == JwtTokenType.AccessToken ? DateTime.UtcNow.AddMinutes(15) : DateTime.UtcNow.AddDays(14); } return(cookieOptions); }
private static Exception CreateJwtDescriptorException_ClaimMustBeOfType(ReadOnlySpan <byte> utf8Name, JwtTokenType type) { var value = Utf8.GetString(utf8Name); return(new JwtDescriptorException($"The claim '{value}' must be of type {type}.")); }
internal static void ThrowJwtDescriptorException_ClaimMustBeOfType(ReadOnlySpan <byte> utf8Name, JwtTokenType type) => throw CreateJwtDescriptorException_ClaimMustBeOfType(utf8Name, type);
private static Exception CreateInvalidOperationException_NotSupportedJsonType(JwtTokenType type) => new InvalidOperationException($"The type {type} is not supported.");
internal static void ThrowInvalidOperationException_NotSupportedJsonType(JwtTokenType type) => throw CreateInvalidOperationException_NotSupportedJsonType(type);
/// <summary> /// Initializes a new instance of the <see cref="JwtValue"/> class. /// </summary> /// <param name="value"></param> public JwtValue(JwtArray value) { Type = JwtTokenType.Array; Value = value; }
/// <summary> /// Initializes a new instance of the <see cref="JwtValue"/> class. /// </summary> /// <param name="value"></param> public JwtValue(bool value) { Type = JwtTokenType.Boolean; Value = value; }
/// <summary> /// Initializes a new instance of the <see cref="JwtValue"/> class. /// </summary> /// <param name="value"></param> public JwtValue(float value) { Type = JwtTokenType.Float; Value = (double)value; }
/// <summary> /// Initializes a new instance of the <see cref="JwtValue"/> class. /// </summary> /// <param name="value"></param> public JwtValue(double value) { Type = JwtTokenType.Float; Value = value; }
/// <summary> /// Initializes a new instance of the <see cref="JwtValue"/> class. /// </summary> /// <param name="value"></param> public JwtValue(long value) { Type = JwtTokenType.Integer; Value = value; }
private (string, DateTime) CreateToken(IEnumerable <Claim> claims, JwtOptions options, JwtTokenType tokenType, RefreshToken refreshToken = null) { string secret = options.Secret; if (secret == null) { throw new OsharpException("创建JwtToken时Secret为空,请在OSharp:Jwt:Secret节点中进行配置"); } DateTime expires; DateTime now = DateTime.UtcNow; if (tokenType == JwtTokenType.AccessToken) { if (refreshToken != null) { throw new OsharpException("创建 AccessToken 时不需要 refreshToken"); } double minutes = options.AccessExpireMins > 0 ? options.AccessExpireMins : 5; //默认5分钟 expires = now.AddMinutes(minutes); } else { if (refreshToken == null || !options.IsRefreshAbsoluteExpired) { double minutes = options.RefreshExpireMins > 0 ? options.RefreshExpireMins : 10080; // 默认7天 expires = now.AddMinutes(minutes); } else { expires = refreshToken.EndUtcTime; } } SecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); SigningCredentials credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature); SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor() { Subject = new ClaimsIdentity(claims), Audience = options.Audience, Issuer = options.Issuer, SigningCredentials = credentials, NotBefore = now, IssuedAt = now, Expires = expires }; SecurityToken token = _tokenHandler.CreateToken(descriptor); string accessToken = _tokenHandler.WriteToken(token); return(accessToken, expires); }
protected (string, DateTime) CreateTokenCore(IEnumerable <Claim> claims, JwtOptions options, JwtTokenType tokenType) { string secret = options.Secret; if (secret == null) { throw new RyeException("创建JwtToken时Secret为空,Framework:Jwt:Secret节点中进行配置"); } DateTime expires; DateTime now = DateTime.UtcNow; claims = claims.Append(new Claim("TokenType", ((int)tokenType).ToString())); if (tokenType == JwtTokenType.AccessToken) { double minutes = options.AccessExpireMins > 0 ? options.AccessExpireMins : 5; //默认5分钟 expires = now.AddMinutes(minutes); } else { double minutes = options.RefreshExpireMins > 0 ? options.RefreshExpireMins : 10080; // 默认7天 expires = now.AddMinutes(minutes); } SecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); SigningCredentials credentials = new SigningCredentials(key, options.Encrypt); SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor() { Subject = new ClaimsIdentity(claims), SigningCredentials = credentials, Expires = expires, NotBefore = now, IssuedAt = now, Audience = options.Audience, Issuer = options.Issuer, }; SecurityToken token = _tokenHandler.CreateToken(descriptor); string accessToken = _tokenHandler.WriteToken(token); return(accessToken, expires); }