如何使用新的MVC5身份验证与现有的数据库
问题描述:
我已经浏览了当前的文献,但我正在努力研究如何使新的IdentityStore
系统与您自己的数据库一起工作。如何使用新的MVC5身份验证与现有的数据库
我的数据库的用户表被称为tblMember
下面是一个示例类。
public partial class tblMember
{
public int id { get; set; }
public string membership_id { get; set; }
public string password { get; set; }
....other fields
}
当前用户的登录与membership_id
这是独一无二的,然后我用整个系统,这是主键ID。我无法使用用户名方案登录,因为它在此系统上不够独特。
我看过的例子看起来像系统是我设计的相当可塑,但我目前不能锻炼如何获得本地登录使用我的tblmember
表使用membership_id
进行身份验证,然后我将有权访问用户通过用户属性从任何控制器记录记录。
答
假设你使用的是EF,你应该能够做这样的事情:
public partial class tblMember : IUserSecret
{
public int id { get; set; }
public string membership_id { get; set; }
public string password { get; set; }
....other fields
/// <summary>
/// Username
/// </summary>
string UserName { get { return membership_id; set { membership_id = value; }
/// <summary>
/// Opaque string to validate the user, i.e. password
/// </summary>
string Secret { get { return password; } set { password = value; } }
}
基本上,本地密码存储在新的系统,称为IUserSecretStore。你应该能够在你的实体类型插入的AccountController构造像这样假设你实现一切正常:
public AccountController()
{
var db = new IdentityDbContext<User, UserClaim, tblMember, UserLogin, Role, UserRole>();
StoreManager = new IdentityStoreManager(new IdentityStoreContext(db));
}
注意用户属性将包含用户的索赔,并要求的NameIdentifier将映射到IUser.Id身份系统中的财产。这并不直接与只是用户名/秘密存储的IUserSecret绑定。该系统模型本地密码作为本地登录与providerKey =用户名和loginProvider =“本地”
编辑:添加自定义用户的实例以及
public class CustomUser : User {
public string CustomProperty { get; set; }
}
public class CustomUserContext : IdentityStoreContext {
public CustomUserContext(DbContext db) : base(db) {
Users = new UserStore<CustomUser>(db);
}
}
[TestMethod]
public async Task IdentityStoreManagerWithCustomUserTest() {
var db = new IdentityDbContext<CustomUser, UserClaim, UserSecret, UserLogin, Role, UserRole>();
var manager = new IdentityStoreManager(new CustomUserContext(db));
var user = new CustomUser() { UserName = "Custom", CustomProperty = "Foo" };
string pwd = "password";
UnitTestHelper.IsSuccess(await manager.CreateLocalUserAsync(user, pwd));
Assert.IsTrue(await manager.ValidateLocalLoginAsync(user.UserName, pwd));
CustomUser fetch = await manager.Context.Users.FindAsync(user.Id) as CustomUser;
Assert.IsNotNull(fetch);
Assert.AreEqual("Custom", fetch.UserName);
Assert.AreEqual("Foo", fetch.CustomProperty);
}
编辑#2: IdentityAuthenticationmanager.GetUserClaims的实现中还存在一个错误,该错误将投射到用户而不是IUser,因此未从用户扩展的自定义用户将无法工作。
下面是您可以用它来重写代码:
internal const string IdentityProviderClaimType = "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider";
internal const string DefaultIdentityProviderClaimValue = "ASP.NET Identity";
/// <summary>
/// Return the claims for a user, which will contain the UserIdClaimType, UserNameClaimType, a claim representing each Role
/// and any claims specified in the UserClaims
/// </summary>
public override async Task<IList<Claim>> GetUserIdentityClaims(string userId, IEnumerable<Claim> claims) {
List<Claim> newClaims = new List<Claim>();
User user = await StoreManager.Context.Users.Find(userId) as IUser;
if (user != null) {
bool foundIdentityProviderClaim = false;
if (claims != null) {
// Strip out any existing name/nameid claims that may have already been set by external identities
foreach (var c in claims) {
if (!foundIdentityProviderClaim && c.Type == IdentityProviderClaimType) {
foundIdentityProviderClaim = true;
}
if (c.Type != ClaimTypes.Name &&
c.Type != ClaimTypes.NameIdentifier) {
newClaims.Add(c);
}
}
}
newClaims.Add(new Claim(UserIdClaimType, userId, ClaimValueTypes.String, ClaimsIssuer));
newClaims.Add(new Claim(UserNameClaimType, user.UserName, ClaimValueTypes.String, ClaimsIssuer));
if (!foundIdentityProviderClaim) {
newClaims.Add(new Claim(IdentityProviderClaimType, DefaultIdentityProviderClaimValue, ClaimValueTypes.String, ClaimsIssuer));
}
var roles = await StoreManager.Context.Roles.GetRolesForUser(userId);
foreach (string role in roles) {
newClaims.Add(new Claim(RoleClaimType, role, ClaimValueTypes.String, ClaimsIssuer));
}
IEnumerable<IUserClaim> userClaims = await StoreManager.Context.UserClaims.GetUserClaims(userId);
foreach (IUserClaim uc in userClaims) {
newClaims.Add(new Claim(uc.ClaimType, uc.ClaimValue, ClaimValueTypes.String, ClaimsIssuer));
}
}
return newClaims;
}
能否请您提供一个完整的例子。我想用我自己的用户类映射到我的用户表。看起来像我不是唯一一个寻找解决方案:http://stackoverflow.com/questions/17399933/how-do-i-configure-the-users-context-table –
编辑我的答案包含一个自定义用户,你可能会实现IUser而不是扩展用户,但其余的代码应该是一样的 –
@霍恭,我目前混淆了如何正确实现这一点,我明白,这仍然在测试版,但在那里似乎没有关于自定义和链接到您自己的数据库/密码存储的实际细节,是否还有更多您意识到的示例/资源? – Tim