otkalce

Authentication - user registration in memory

Mar 10th, 2023 (edited)
344
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.62 KB | Source Code | 0 0
  1. // *** Program.cs: Turn of automatic error 400 ***
  2. builder.Services.Configure<ApiBehaviorOptions>(options => {
  3.     options.SuppressModelStateInvalidFilter = true;
  4. });
  5.  
  6. // *** Model - used internally ***
  7.     public class User {
  8.         public int Id { get; set; }
  9.         public string Username { get; set; }
  10.         public string Email { get; set; }
  11.         public string PwdHash { get; set; }
  12.         public string PwdSalt { get; set; }
  13.         public string Phone { get; set; }
  14.         public bool IsConfirmed { get; set; }
  15.         public string SecurityToken { get; set; }
  16.     }
  17.  
  18. // *** Request model - passed to action, used to create model ***
  19.     public class UserRegisterRequest
  20.     {
  21.         [Required, StringLength(50, MinimumLength = 6)]
  22.         public string Username { get; set; }
  23.         [Required]
  24.         public string Password { get; set; }
  25.         [Required]
  26.         public string Email { get; set; }
  27.         public string Phone { get; set; }
  28.     }
  29.  
  30. // *** Response model - returned from action, used as response ***
  31.     public class UserRegisterResponse
  32.     {
  33.         public int Id { get; set; }
  34.         public string SecurityToken { get; set; }
  35.     }
  36.  
  37. // *** UserController POST action for registering a new user ***
  38.         [HttpPost("[action]")]
  39.         public ActionResult<User> Register([FromBody] UserRegisterRequest request)
  40.         {
  41.             if(!ModelState.IsValid)
  42.                 return BadRequest(ModelState);
  43.  
  44.             try
  45.             {
  46.                 // Username: Normalize and check if username exists
  47.                 var normalizedUsername = request.Username.ToLower().Trim();
  48.                 if (_users.Any(x => x.Username.Equals(normalizedUsername)))
  49.                     throw new InvalidOperationException("Username already exists");
  50.  
  51.                 // Password: Salt and hash password
  52.                 byte[] salt = RandomNumberGenerator.GetBytes(128 / 8); // divide by 8 to convert bits to bytes
  53.                 string b64Salt = Convert.ToBase64String(salt);
  54.  
  55.                 byte[] hash =
  56.                     KeyDerivation.Pbkdf2(
  57.                         password: request.Password,
  58.                         salt: salt,
  59.                         prf: KeyDerivationPrf.HMACSHA256,
  60.                         iterationCount: 100000,
  61.                         numBytesRequested: 256 / 8);
  62.                 string b64Hash = Convert.ToBase64String(hash);
  63.  
  64.                 // SecurityToken: Random security token
  65.                 byte[] securityToken = RandomNumberGenerator.GetBytes(256 / 8);
  66.                 string b64SecToken = Convert.ToBase64String(securityToken);
  67.  
  68.                 // Id: Next id
  69.                 int nextId = 1;
  70.                 if (_users.Any())
  71.                 {
  72.                     nextId = _users.Max(x => x.Id) + 1;
  73.                 }
  74.  
  75.                 // New user
  76.                 var newUser = new User
  77.                 {
  78.                     Id = nextId,
  79.                     Username = request.Username,
  80.                     Email = request.Email,
  81.                     Phone = request.Phone,
  82.                     IsConfirmed = false,
  83.                     SecurityToken = b64SecToken,
  84.                     PwdSalt = b64Salt,
  85.                     PwdHash = b64Hash
  86.                 };
  87.                 _users.Add(newUser);
  88.  
  89.                 return Ok(new UserRegisterResponse
  90.                 {
  91.                     Id = newUser.Id,
  92.                     SecurityToken = newUser.SecurityToken
  93.                 });
  94.             }
  95.             catch (InvalidOperationException ex)
  96.             {
  97.                 return BadRequest(ex.Message);
  98.             }
  99.         }
  100.  
  101.  
Add Comment
Please, Sign In to add comment