I don't know if my title is correct. But I have a simple problem.
I can't login. And is this because the encrypted data
i cannot decrypt
it properly?
Basically, I have a register method.
And this is my AuthRepository
public class AuthRepository : IAuthRepository
{
private readonly DataContext _context;
public AuthRepository(DataContext context)
{
_context = context;
}
public async Task<User> Login(string username, string password)
{
var user = await _context.Users.FirstOrDefaultAsync(x => x.Username == username);
if (user == null)
return null;
if (!VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt))
return null;
return user;
}
private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
{
using (var hmac = new System.Security.Cryptography.HMACSHA512())
{
var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
for (int i = 0; i < computedHash.Length; i++)
{
if (computedHash[i] != passwordHash[i])
return false;
}
}
return true;
}
public async Task<User> Register(User user, string password)
{
byte[] passwordHash, passwordSalt;
CreatePasswordHash(password, out passwordHash, out passwordSalt);
user.PasswordHash = passwordHash;
user.PasswordSalt = passwordSalt;
await _context.Users.AddAsync(user);
await _context.SaveChangesAsync();
return user;
}
private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
{
using (var hmac = new System.Security.Cryptography.HMACSHA512())
{
passwordSalt = hmac.Key;
passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
}
}
public async Task<bool> UserExists(string username)
{
if (await _context.Users.AnyAsync(x => x.Username == username))
return true;
return false;
}
}
My register
is working. I tested it using Postman
But why i can't login?
Is there any wrong with my decrpyting
the encrypted
data when the user is registered
I've been trying to solve for hours now. But i can't make it work. I am following a video tutorial. But i can't find the difference with the one in the tutorial and mine.
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly IAuthRepository _repo;
private readonly IConfiguration _config;
public AuthController(IAuthRepository repo, IConfiguration config)
{
_repo = repo;
_config = config;
}
[HttpPost("register")]
public async Task<IActionResult> Register(UserForRegisterDto userForRegisterDto)
{
userForRegisterDto.Username = userForRegisterDto.Username.ToLower();
if (await _repo.UserExists(userForRegisterDto.Username))
return BadRequest("Username already exist");
var userToCreate = new User
{
Username = userForRegisterDto.Username
};
var createdUser = await _repo.Register(userToCreate, userForRegisterDto.Password);
return StatusCode(201);
}
[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
{
var userFromRepo = await _repo.Login(userForLoginDto.Username.ToLower(), userForLoginDto.Password);
if (userFromRepo == null)
return Unauthorized();
return Ok();
}
}
I'm really stuck into this part. Please help me. Thank you.
I didn't encountered any error.
But i noticed this when i debug the program
The array result is not the same. Is this the reason of the Unauthorized login
If so. How can i properly validate the username and password.
I also checked if the username and password i passed in the web api is correct (plain text).
I have checked the problem is when you are creating and comparing the object of System.Security.Cryptography.HMACSHA512() because of this it always generate a different hash. Solution for this is to declare a global object for this class and you have to use the object when you are creating and verifying the hash. I have checked it. It working fine in my case after declaring globally.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.