JwtAuthController.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IdentityModel.Tokens.Jwt;
  4. using System.Security.Claims;
  5. using System.Text;
  6. using BubbleSocketCore.Library;
  7. using Microsoft.AspNetCore.Http;
  8. using Microsoft.AspNetCore.Mvc;
  9. using Microsoft.Extensions.Configuration;
  10. using Microsoft.Extensions.Logging;
  11. using Microsoft.IdentityModel.Tokens;
  12. namespace BubbleSocketCore.Controllers
  13. {
  14. [ApiController]
  15. [Route("jwt")]
  16. [Produces("application/json")]
  17. public class JwtAuthController : ControllerBase
  18. {
  19. private readonly ILogger<JwtAuthController> Logger;
  20. private readonly IConfiguration Configuration;
  21. private readonly SHA256HashGenerator sha256HashGenerator;
  22. private readonly JsonFileManager JsonFileManager;
  23. public JwtAuthController(ILogger<JwtAuthController> logger, IConfiguration configuration)
  24. {
  25. Logger = logger;
  26. Configuration = configuration;
  27. sha256HashGenerator = SHA256HashGenerator.GetInstance();
  28. JsonFileManager = new JsonFileManager(configuration);
  29. }
  30. [HttpPost]
  31. [Route("login")]
  32. public IActionResult Login([FromBody] LoginModel model)
  33. {
  34. if (!DoesPasswordMatch(model.Username, model.Password))
  35. {
  36. return Unauthorized();
  37. }
  38. var authClaims = new List<Claim>
  39. {
  40. new Claim(ClaimTypes.Name, model.Username),
  41. new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
  42. };
  43. var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSettings:SecretKey"]));
  44. var token = new JwtSecurityToken(
  45. issuer: Configuration["JwtSettings:Issuer"],
  46. audience: Configuration["JwtSettings:Audience"],
  47. expires: DateTime.Now.AddHours(Configuration.GetValue<int>("JwtSettings:ExpirationInHours")),
  48. claims: authClaims,
  49. signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
  50. );
  51. Logger.LogInformation($"User '{model.Username}' logged in.");
  52. return Ok(new
  53. {
  54. token = new JwtSecurityTokenHandler().WriteToken(token),
  55. expiration = token.ValidTo
  56. });
  57. }
  58. private bool DoesPasswordMatch(string username, string password)
  59. {
  60. if (!JsonFileManager.DoesAccountAlreadyExist(username))
  61. {
  62. return false;
  63. }
  64. var accountInfo = JsonFileManager.ReadAccountFile(username);
  65. var hashedPassword = accountInfo.GetProperty("Password").GetString();
  66. var inputPasswordHashed = sha256HashGenerator.Get(password + Configuration.GetValue<string>("ServerSalt"));
  67. return hashedPassword.Equals(inputPasswordHashed);
  68. }
  69. [HttpPost]
  70. [Route("register")]
  71. public IActionResult Register([FromBody] RegisterModel model)
  72. {
  73. if (JsonFileManager.DoesAccountAlreadyExist(model.Username))
  74. {
  75. dynamic errorObject = new
  76. {
  77. errorCode = StatusCodes.Status409Conflict,
  78. errorMessage = "409 Error: That user is already registered.",
  79. username = model.Username
  80. };
  81. return StatusCode(errorObject.errorCode, errorObject);
  82. }
  83. var data = new
  84. {
  85. Username = model.Username,
  86. Password = sha256HashGenerator.Get(model.Password + Configuration.GetValue<string>("ServerSalt")),
  87. Email = model.Email,
  88. AccountId = Guid.NewGuid().ToString()
  89. };
  90. JsonFileManager.WriteAccountFile(model.Username, data);
  91. Logger.LogInformation($"User '{model.Username}' registered.");
  92. return Ok("Account Created");
  93. }
  94. public class LoginModel
  95. {
  96. public LoginModel() { }
  97. public LoginModel(string username, string password)
  98. {
  99. Username = username;
  100. Password = password;
  101. }
  102. public string Username { get; set; }
  103. public string Password { get; set; }
  104. }
  105. public class RegisterModel
  106. {
  107. public RegisterModel() { }
  108. public RegisterModel(string username, string password, string email)
  109. {
  110. Username = username;
  111. Password = password;
  112. Email = email;
  113. }
  114. public string Username { get; set; }
  115. public string Password { get; set; }
  116. public string Email { get; set; }
  117. }
  118. }
  119. }