10

私は現在の文献を調べましたが、新しいIdentityStoreシステムを独自のデータベースで機能させる方法を正確に理解するのに苦労しています.

私のデータベースの User テーブルは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ん。 User プロパティを介したコントローラの。

http://blogs.msdn.com/b/webdev/archive/2013/07/03/understanding-owin-forms-authentication-in-mvc-5.aspx

4

1 に答える 1

5

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));
    }

User プロパティにはユーザーのクレームが含まれ、NameIdentifier クレームは ID システムの IUser.Id プロパティにマップされることに注意してください。これは、単なるユーザー名/シークレット ストアである IUserSecret に直接関連付けられているわけではありません。システムは、ローカル パスワードを、providerKey = ユーザー名、loginProvider = "Local" のローカル ログインとしてモデル化します。

編集:カスタムユーザーの例も追加

    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 ではなく User にキャストするバグもあるため、User から拡張されていないカスタム ユーザーは機能しません。

オーバーライドに使用できるコードは次のとおりです。

    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;
}
于 2013-07-15T23:02:12.627 に答える