假設你使用的是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