如何在 asp.net web api 2 中自定义对我自己的一组表的身份验证?

Posted

技术标签:

【中文标题】如何在 asp.net web api 2 中自定义对我自己的一组表的身份验证?【英文标题】:How to customize authentication to my own set of tables in asp.net web api 2? 【发布时间】:2013-12-30 00:45:53 【问题描述】:

在我看到的默认 AccountController 创建中

    public AccountController()
        : this(Startup.UserManagerFactory(), Startup.OAuthOptions.AccessTokenFormat)
    
    

在 Startup.Auth.cs 我看到

    UserManagerFactory = () => 
                new UserManager<IdentityUser>(new UserStore<IdentityUser>());   

UserStore 的实现似乎来自 Microsoft.AspNet.Identity.EntityFramework

所以,要自定义身份验证,我是否必须实现我自己的 UserStore 版本,例如

 class MYSTUFFUserStore<IdentityUser> : UserStore<IdentityUser>
 
  

并覆盖方法,然后在 Startup.Auth.cs 中执行此操作

UserManagerFactory = () => 
               new UserManager<IdentityUser>(new MYSTUFFUserStore<IdentityUser>());   

我正在寻找自定义身份验证的正确方法。

【问题讨论】:

【参考方案1】:

假设你的表被称为AppUser,像这样将你自己的AppUser域对象转换为IUser(using Microsoft.AspNet.Identity)

using Microsoft.AspNet.Identity;
public class AppUser : IUser

    //Existing database fields
    public long AppUserId  get; set; 
    public string AppUserName  get; set; 
    public string AppPassword  get; set; 

    public AppUser()
    
        this.Id = Guid.NewGuid().ToString();  
    

    [Ignore]
    public virtual string Id  get; set;          
    [Ignore]
    public string UserName
    
        get
        
            return AppUserName;
        
        set
        
            AppUserName = value;
        
    

像这样实现UserStore 对象

using Microsoft.AspNet.Identity;
public class UserStoreService 
         : IUserStore<AppUser>, IUserPasswordStore<AppUser>

    CompanyDbContext context = new CompanyDbContext();

    public Task CreateAsync(AppUser user)
                
        throw new NotImplementedException();
    

    public Task DeleteAsync(AppUser user)
    
        throw new NotImplementedException();
    

    public Task<AppUser> FindByIdAsync(string userId)
    
        throw new NotImplementedException();
    

    public Task<AppUser> FindByNameAsync(string userName)
    
        Task<AppUser> task = context.AppUsers.Where(
                              apu => apu.AppUserName == userName)
                              .FirstOrDefaultAsync();

        return task;
    

    public Task UpdateAsync(AppUser user)
    
        throw new NotImplementedException();
    

    public void Dispose()
    
        context.Dispose();
    

    public Task<string> GetPasswordHashAsync(AppUser user)
    
        if (user == null)
        
            throw new ArgumentNullException("user");
        

        return Task.FromResult(user.AppPassword);
    

    public Task<bool> HasPasswordAsync(AppUser user)
    
        return Task.FromResult(user.AppPassword != null);
    

    public Task SetPasswordHashAsync(AppUser user, string passwordHash)
    
        throw new NotImplementedException();
    


如果您有自己的自定义密码哈希,您还需要实现IPasswordHasher。下面是一个没有密码散列的例子(哦,不!)

using Microsoft.AspNet.Identity;
public class MyPasswordHasher : IPasswordHasher

    public string HashPassword(string password)
    
        return password;
    

    public PasswordVerificationResult VerifyHashedPassword
                  (string hashedPassword, string providedPassword)
    
        if (hashedPassword == HashPassword(providedPassword))
            return PasswordVerificationResult.Success;
        else
            return PasswordVerificationResult.Failed;
    

在 Startup.Auth.cs 中替换

UserManagerFactory = () => 
     new UserManager<IdentityUser>(new UserStore<IdentityUser>());

    UserManagerFactory = () => 
     new UserManager<AppUser>(new UserStoreService())  PasswordHasher = new MyPasswordHasher() ;

ApplicationOAuthProvider.cs 中,将IdentityUser 替换为AppUser

AccountController.cs中,将IdentityUser替换为AppUser,并删除GetManageInfoRegisterExternal等所有外部认证方式。

【讨论】:

感谢您的回答,但是对于当前请求,我如何从另一个控制器获取AppUser User.Identity.Name 将在经过身份验证的请求中为您提供用户名。 Sunil,你能解释一下为什么自定义类“AppUser”需要实现内置接口“IUser”吗? @Thomas.Benz 这是我发现有用的一篇文章中的一个 sn-p:“Microsoft.AspNet.Identity.UserManager where T: IUser 这个类允许创建、删除和查找用户以及创建身份。身份是为用户创建的,可用于做出授权和身份验证决策。这里的想法是使用 ASP.NET Identity 的一些/大部分内置功能,然后使用自定义实现覆盖/替换您需要的功能 - 至少这就是我在这里所做的,这要归功于 Sunil 的回答

以上是关于如何在 asp.net web api 2 中自定义对我自己的一组表的身份验证?的主要内容,如果未能解决你的问题,请参考以下文章