From d5944c470b9272c6b059b6ea9cf8dac174810dbf Mon Sep 17 00:00:00 2001 From: Kun Deng Date: Sun, 4 Sep 2022 20:34:33 -0400 Subject: [PATCH] Symmetric keys with jwt has been implemented --- Controllers/Managers/TokenManager.cs | 55 +++++++++++++++++++++++--- Controllers/v1/LoginController.cs | 49 ++++++++++++++--------- Controllers/v1/SongStreamController.cs | 3 ++ Startup.cs | 2 +- 4 files changed, 83 insertions(+), 26 deletions(-) diff --git a/Controllers/Managers/TokenManager.cs b/Controllers/Managers/TokenManager.cs index c00452f..08c0a15 100644 --- a/Controllers/Managers/TokenManager.cs +++ b/Controllers/Managers/TokenManager.cs @@ -4,10 +4,14 @@ using System.Linq; using System.Security.Claims; using System.Security.Cryptography; using System.Threading.Tasks; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; using JWT; using JWT.Serializers; using Microsoft.Extensions.Configuration; +using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; @@ -113,6 +117,40 @@ namespace Icarus.Controllers.Managers }; } + public LoginResult LoginSymmetric(User user) + { + var tokenResult = new TokenTierOne(); + tokenResult.TokenType = "Jwt"; + + var payload = Payload(); + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JWT:Secret"])); + var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + var token = new JwtSecurityToken( + _config["JWT:Issuer"], + _config["JWT:Audience"], + payload, + expires: DateTime.UtcNow.AddMinutes(30), + signingCredentials: signIn); + + tokenResult.AccessToken = new JwtSecurityTokenHandler().WriteToken(token); + + var expClaim = payload.FirstOrDefault(cl => + { + return cl.Type.Equals("exp"); + }); + + var expiredDate = DateTime.Parse(expClaim.Value); + var exp = Math.Floor((expiredDate - DateTime.UnixEpoch).TotalSeconds); + tokenResult.Expiration = Convert.ToInt32(exp); + + return new LoginResult + { + UserID = user.UserID, Username = user.Username, Token = tokenResult.AccessToken, + TokenType = tokenResult.TokenType, Expiration = tokenResult.Expiration, + Message = "Successfully retrieved token" + }; + } + public bool IsTokenValid(string scope, string accessToken) { var result = false; @@ -201,23 +239,28 @@ namespace Icarus.Controllers.Managers private List Payload() { - const int expLimit = 24; + var expLimit = 30; var currentDate = DateTime.Now; - var expiredDate = currentDate.AddHours(expLimit); + var expiredDate = currentDate.AddMinutes(expLimit); var issued = Math.Floor((currentDate - DateTime.UnixEpoch).TotalSeconds); var expires = Math.Floor((expiredDate - DateTime.UnixEpoch).TotalSeconds); var issuer = "https://soaricarus.auth0.com"; issuer = "http://localhost:5002"; var audience = "https://icarus/api"; audience = "http://localhost:5002"; + var subject = _config["JWT:Subject"]; var claim = new List() { new System.Security.Claims.Claim("scope", AllScopes(), "string"), - new System.Security.Claims.Claim("exp", $"{expires}", "integer"), - new System.Security.Claims.Claim("aud", $"{audience}", "string"), - new System.Security.Claims.Claim("iss", $"{issuer}", "string"), - new System.Security.Claims.Claim("iat", $"{issued}", "integer") + // new System.Security.Claims.Claim("exp", $"{expires}", "integer"), + new System.Security.Claims.Claim(JwtRegisteredClaimNames.Exp, expiredDate.ToString()), + // new System.Security.Claims.Claim("aud", $"{audience}", "string"), + new System.Security.Claims.Claim(JwtRegisteredClaimNames.Aud, audience), + // new System.Security.Claims.Claim("iss", $"{issuer}", "string"), + new System.Security.Claims.Claim(JwtRegisteredClaimNames.Iss, issuer), + new Claim(JwtRegisteredClaimNames.Sub, subject), + new System.Security.Claims.Claim(JwtRegisteredClaimNames.Iat, currentDate.ToString()) }; return claim; diff --git a/Controllers/v1/LoginController.cs b/Controllers/v1/LoginController.cs index 78ee567..881e3d9 100644 --- a/Controllers/v1/LoginController.cs +++ b/Controllers/v1/LoginController.cs @@ -55,34 +55,45 @@ namespace Icarus.Controllers.V1 Username = user.Username }; - if (context.Users.FirstOrDefault(usr => usr.Username.Equals(user.Username)) != null) + try { - user = context.Users.FirstOrDefault(usr => usr.Username.Equals(user.Username)); - - var validatePass = new PasswordEncryption(); - var validated = validatePass.VerifyPassword(user, password); - if (!validated) + if (context.Users.FirstOrDefault(usr => usr.Username.Equals(user.Username)) != null) { - loginRes.Message = message; - _logger.LogInformation(message); + user = context.Users.FirstOrDefault(usr => usr.Username.Equals(user.Username)); + + var validatePass = new PasswordEncryption(); + var validated = validatePass.VerifyPassword(user, password); + if (!validated) + { + loginRes.Message = message; + _logger.LogInformation(message); + + return Ok(loginRes); + } + + _logger.LogInformation("Successfully validated user credentials"); + + TokenManager tk = new TokenManager(_config); + + // loginRes = tk.LogIn(user); + loginRes = tk.LoginSymmetric(user); return Ok(loginRes); } + else + { + loginRes.Message = message; - _logger.LogInformation("Successfully validated user credentials"); - - TokenManager tk = new TokenManager(_config); - - loginRes = tk.LogIn(user); - - return Ok(loginRes); + return NotFound(loginRes); + } } - else + catch (Exception ex) { - loginRes.Message = message; - - return NotFound(loginRes); + _logger.LogError("An error occurred: {0}", ex.Message); + _logger.LogError("Inner Exception: {0}", ex.InnerException.Message); } + + return NotFound(loginRes); } #endregion } diff --git a/Controllers/v1/SongStreamController.cs b/Controllers/v1/SongStreamController.cs index b273a08..4479800 100644 --- a/Controllers/v1/SongStreamController.cs +++ b/Controllers/v1/SongStreamController.cs @@ -20,6 +20,7 @@ namespace Icarus.Controllers.V1 { [Route("api/v1/song/stream")] [ApiController] + [Authorize] public class SongStreamController : BaseController { #region Fields @@ -46,10 +47,12 @@ namespace Icarus.Controllers.V1 [HttpGet("{id}")] public async Task Get(int id) { + /** if (!IsTokenValid("stream:songs")) { return StatusCode(401, "Not allowed"); } + */ var context = new SongContext(_config.GetConnectionString("DefaultConnection")); diff --git a/Startup.cs b/Startup.cs index af349a3..7462694 100644 --- a/Startup.cs +++ b/Startup.cs @@ -95,7 +95,7 @@ namespace Icarus services.AddDbContext(options => options.UseMySQL(connString)); services.AddDbContext(options => options.UseMySQL(connString)); - services.AddAsymmetricAuthentication(Configuration); + // services.AddAsymmetricAuthentication(Configuration); /** services.AddTransient(au => new AuthenticationService(new UserService(Configuration), new TokenService(Configuration), Configuration));