ASP.NET MVC中的简单,硬编码授权,没有复杂的提供程序和数据库

时间:2014-01-27 01:39:54

标签: asp.net asp.net-mvc authentication

我有一个MVC应用程序,我只有四个用户帐户。由于它们只是不会真正改变的管理员帐户,所以我不想处理ASP.NET MVC中的数据库和所有成员资格选项。我只需要一个非常简单的机制来检查一些管理员帐户并授权用户(或不授权)。我知道这根本不是一个好习惯,但它完全适合我的情况:

有一个Web应用程序具有Web API,所有(未经授权的)用户都通过Web API与我的应用程序对话。有许多控制器仅供管理员使用,并且使用[Authorize]属性进行修饰。所有页面管理员登录。该网站工作正常,但我无法创建登录系统。每当我尝试登录(使用任何凭据)时,我都会收到The entity type ApplicationUser is not part of the model for the current context.错误消息。我没有ApplicationUser实体模型。我从来没有过。我也不需要它。这发生在以下自动生成的行上:

var user = await UserManager.FindAsync(model.UserName, model.Password);

如何摆脱默认的用户管理器和身份验证方法,并使用我极其简单的身份验证方法?我在网上发现的所有文章都非常复杂。我一直在使用经典的ASP.NET,但我是ASP.NET MVC的新手,而我开始了解ASP.NET MVC的工作方式和模式,我找不到一个简单的会员/授权起点。我只是需要检查一些用户名和密码,无需需要数据库。

1 个答案:

答案 0 :(得分:5)

假设您的表名为AppUser,请将您自己的 AppUser 域对象转换为 IUser (使用Microsoft.AspNet.Identity),如下所示

using Microsoft.AspNet.Identity; 
public class AppUser : IUser 
{ 
    //Existing database fields 
    public long AppUserId { get; set; } 
    public long 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 对象(您必须自定义 FindByNameAsync 以满足您的要求。这里我显示了自定义数据库上下文)

using Microsoft.AspNet.Identity;
public class UserStoreService : 
    IUserStore<AppUser>, IUserPasswordStore<AppUser>, 
    IUserSecurityStampStore<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();
    }

    public Task<string> GetSecurityStampAsync(AppUser user)
    {
        throw new NotImplementedException();
    }

    public Task SetSecurityStampAsync(AppUser user, string stamp)
    {
        throw new NotImplementedException();
    }
}

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

using Microsoft.AspNet.Identity;
public class PasswordHasher : 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>());

var userManager = new UserManager<AppUser>(new UserStoreService());
userManager.PasswordHasher = new PasswordHasher();
UserManagerFactory = () => userManager;

ApplicationOAuthProvider.cs 中,将 IdentityUser 替换为 AppUser AccountController.cs 中,替换 IdentityUser 使用AppUser并删除所有外部身份验证方法,例如 GetManageInfo RegisterExternal 等。