Reputation: 34830
I have an MVC app that I have only four user accounts. Since they are only admin accounts that won't really be changing, I don't want to deal with database and all the membership options in ASP.NET MVC. I just need a very simple mechanism that checks for a few admin accounts and authorizes the user (or not). I know it's not a good practice at all, but it suits my situation perfectly:
There is a web app that has Web API and all the (unauthorized) users speak to my app through the Web API. There are many controllers that are for the admins only, and they are decorated with the [Authorize]
attribute. All the pages admin login. The site is working perfectly except that I couldn't create the login system. Whenever I try to login (with any credentials), I'm getting The entity type ApplicationUser is not part of the model for the current context.
error message. I don't have an ApplicationUser
entity model. I never had either. I don't need it either. This happens on the following auto-generated line:
var user = await UserManager.FindAsync(model.UserName, model.Password);
How can I get rid of the default user manager and authentication methods, and use my extremely simple authentication method? All the articles that I've found online are extremely complicated. I've been using classic ASP.NET but I'm new to ASP.NET MVC, while I started to get how ASP.NET MVC works and it's patterns, and I can't find an easy starting point for membership/authorization. I just need to check for a few usernames and passwords only, without the need for a database.
Upvotes: 6
Views: 4624
Reputation: 5168
Assuming your table is called AppUser, convert your own AppUser domain object to IUser(using Microsoft.AspNet.Identity) like this
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; }
}
}
Implement the UserStore object like this(You have to customize FindByNameAsync to fit your requirement. Here I show a custom db context)
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();
}
}
If you have your own custom password hashing you will also need to implement IPasswordHasher. Below is an example where there is no hashing of the password(Oh no!)
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;
}
}
In Startup.Auth.cs replace
UserManagerFactory = () =>
new UserManager<IdentityUser>(new UserStore<IdentityUser>());
with
var userManager = new UserManager<AppUser>(new UserStoreService());
userManager.PasswordHasher = new PasswordHasher();
UserManagerFactory = () => userManager;
In ApplicationOAuthProvider.cs, replace IdentityUser with AppUser In AccountController.cs, replace IdentityUser with AppUser and delete all the external authentication methods like GetManageInfo and RegisterExternal etc.
Upvotes: 8