我有一个MVC6项目(vNext),我正在使用ASP.NET标识。在我的例子中,我不想使用使用EF (SignInManager,UserManager,UserStore)的内置东西。我有一个外部数据库,我只想查找用户名/密码并返回一个有效的cookie。所以我开始编写自己的类。
public class MyUser
{
public string Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string PasswordHash { get; set; }
}
public class MyUserStore : IUserStore<MyUser>, IUserPasswordStore<MyUser>
{
...
}在MyUserStore类中,我使用硬编码的用户列表作为我的存储(仅用于测试目的)。我重写了一些方法,只是为了从硬编码的存储中返回数据。
public class MyUserManager : UserManager<MyUser>
{
public MyUserManager(
IUserStore<MyUser> store,
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<MyUser> passwordHasher,
IEnumerable<IUserValidator<MyUser>> userValidators,
IEnumerable<IPasswordValidator<MyUser>> passwordValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
IEnumerable<IUserTokenProvider<MyUser>> tokenProviders,
ILoggerFactory logger,
IHttpContextAccessor contextAccessor) :
base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, tokenProviders, logger, contextAccessor)
{
}
}这里,我将CheckPasswordAsync和VerifyPasswordAsync方法分别返回true和PasswordVerificationResult.Success,以便于测试。
public class MyClaimsPrincipleFactory : IUserClaimsPrincipalFactory<MyUser>
{
public Task<ClaimsPrincipal> CreateAsync(MyUser user)
{
return Task.Factory.StartNew(() =>
{
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
var principle = new ClaimsPrincipal(identity);
return principle;
});
}
}
public class MySignInManager : SignInManager<MyUser>
{
public MySignInManager(MyUserManager userManager, IHttpContextAccessor contextAccessor, IUserClaimsPrincipalFactory<MyUser> claimsFactory, IOptions<IdentityOptions> optionsAccessor = null, ILoggerFactory logger = null)
: base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger)
{
}
public override Task<SignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
{
// here goes the external username and password look up
if (userName.ToLower() == "username" && password.ToLower() == "password")
{
return base.PasswordSignInAsync(userName, password, isPersistent, shouldLockout);
}
else
{
return Task.FromResult(SignInResult.Failed);
}
}
}并且所有内容都在Startup类中连接起来,如下所示:
services.AddIdentity<MyUser, MyRole>()
.AddUserStore<MyUserStore>()
.AddUserManager<MyUserManager>()
.AddDefaultTokenProviders();而且因为我没有设法在Startup代码中创建MySignInManager对象以便将其添加到DI中(以便稍后在控制器和视图中注入),所以我在MyAccountController中创建它。
public MyAccountController(IHttpContextAccessor httpContextAccessor, UserManager<MyUser> userManager, IOptions<IdentityOptions> optionsAccessor, ILoggerFactory logger)
{
SignInManager = new MySignInManager(userManager as MyUserManager, httpContextAccessor, new MyClaimsPrincipleFactory(), optionsAccessor, logger);
}在MyAccount控制器中的MyLogin操作中,我调用了PasswordSignInAsync,可以看到我正在(从MyClaimsPrincipleFactory)获取包含编码声明的cookie。当我尝试调用带有cookie的其他操作时,我可以看到AuthorizeAttribute在请求标头中,但我是未经授权的(更准确地说,因为我没有从visual studio示例模板中删除内置的默认ASP.NET身份验证,所以我被重定向到帐户/登录)。
这是自定义ASP.NET身份的正确方式吗?我在这里缺少什么?
https://stackoverflow.com/questions/31271600
复制相似问题