patterncsharpMinor
Abstracting a Password Service
Viewed 0 times
abstractingservicepassword
Problem
I want to use
So I can use DI for both
Is this a reasonable way to go about this? Are there any better patterns I can use?
Microsoft.AspNet.Identity's PasswordHasher but I don't want to pollute my Domain layer with knowledge of it. As such I created an interface in my Domain layerpublic interface IPasswordService
{
string HashPassword(string password);
bool VerifyPassword(string hashedPassword, string testPassword);
}So I can use DI for both
IPasswordHasher and IPasswordService I created an adaptor:public class PasswordServiceAdaptor : IPasswordService, IPasswordHasher
{
private readonly PasswordHasher hasher;
public PasswordServiceAdaptor()
{
this.hasher = new PasswordHasher();
}
string IPasswordHasher.HashPassword(string password)
{
return this.hasher.HashPassword(password);
}
PasswordVerificationResult IPasswordHasher.VerifyHashedPassword(
string hashedPassword,
string providedPassword)
{
return this.hasher.VerifyHashedPassword(hashedPassword, providedPassword);
}
string IPasswordService.HashPassword(string password)
{
return this.AsPasswordHasher().HashPassword(password);
}
bool IPasswordService.VerifyPassword(string hashedPassword, string testPassword)
{
var result = this.AsPasswordHasher().VerifyHashedPassword(
hashedPassword,
testPassword);
return result == PasswordVerificationResult.Success;
}
private IPasswordHasher AsPasswordHasher()
{
return this;
}
}Is this a reasonable way to go about this? Are there any better patterns I can use?
Solution
This looks quite good, but as usual improvements can be made.
private readonly PasswordHasher hasher;
instead of using the implementation, you should use the interface
I don't see why you want to use both
As it seems from the comments that you need to implement both interfaces, you should consider to just call the
private readonly PasswordHasher hasher;
instead of using the implementation, you should use the interface
private readonly IPasswordHasher hasher;I don't see why you want to use both
IPasswordHasher and IPasswordService. If your application is built upon IPasswordService you can just skip the implementation of the IPasswordHasher interface like public class PasswordServiceAdaptor : IPasswordService
{
private readonly IPasswordHasher hasher;
public PasswordServiceAdaptor()
{
this.hasher = new PasswordHasher();
}
string IPasswordService.HashPassword(string password)
{
return this.hasher.HashPassword(password);
}
bool IPasswordService.VerifyPassword(string hashedPassword, string testPassword)
{
var result = this.hasher.VerifyHashedPassword(hashedPassword, providedPassword);
return result == PasswordVerificationResult.Success;
}
}As it seems from the comments that you need to implement both interfaces, you should consider to just call the
hasher directly without the call to AsPasswordHasher(). public class PasswordServiceAdaptor : IPasswordService, IPasswordHasher
{
private readonly IPasswordHasher hasher;
public PasswordServiceAdaptor()
{
this.hasher = new PasswordHasher();
}
string IPasswordHasher.HashPassword(string password)
{
return this.hasher.HashPassword(password);
}
PasswordVerificationResult IPasswordHasher.VerifyHashedPassword(
string hashedPassword,
string providedPassword)
{
return this.hasher.VerifyHashedPassword(hashedPassword, providedPassword);
}
string IPasswordService.HashPassword(string password)
{
return this.hasher.HashPassword(password);
}
bool IPasswordService.VerifyPassword(string hashedPassword, string testPassword)
{
var result = this.hasher.VerifyHashedPassword(
hashedPassword,
testPassword);
return result == PasswordVerificationResult.Success;
}
}Code Snippets
private readonly IPasswordHasher hasher;public class PasswordServiceAdaptor : IPasswordService
{
private readonly IPasswordHasher hasher;
public PasswordServiceAdaptor()
{
this.hasher = new PasswordHasher();
}
string IPasswordService.HashPassword(string password)
{
return this.hasher.HashPassword(password);
}
bool IPasswordService.VerifyPassword(string hashedPassword, string testPassword)
{
var result = this.hasher.VerifyHashedPassword(hashedPassword, providedPassword);
return result == PasswordVerificationResult.Success;
}
}public class PasswordServiceAdaptor : IPasswordService, IPasswordHasher
{
private readonly IPasswordHasher hasher;
public PasswordServiceAdaptor()
{
this.hasher = new PasswordHasher();
}
string IPasswordHasher.HashPassword(string password)
{
return this.hasher.HashPassword(password);
}
PasswordVerificationResult IPasswordHasher.VerifyHashedPassword(
string hashedPassword,
string providedPassword)
{
return this.hasher.VerifyHashedPassword(hashedPassword, providedPassword);
}
string IPasswordService.HashPassword(string password)
{
return this.hasher.HashPassword(password);
}
bool IPasswordService.VerifyPassword(string hashedPassword, string testPassword)
{
var result = this.hasher.VerifyHashedPassword(
hashedPassword,
testPassword);
return result == PasswordVerificationResult.Success;
}
}Context
StackExchange Code Review Q#73812, answer score: 4
Revisions (0)
No revisions yet.