2017-02-13 13 views
0

汎用リポジトリパターンでasp net coreのデフォルト認証を使用することはできますか?汎用リポジトリパターンでApplicationUserを使用

デフォルトの方法を使用するプロジェクトの認証側を除いて、すべてのコードに対して一般的なリポジトリパターンを使用するプロジェクトを作成できます。

私のリポジトリは次のようになります。

using System.Linq; 
using DemoWebsite.Interfaces; 
using Microsoft.EntityFrameworkCore; 

namespace DemoWebsite.Data 
{ 
public class Repository<T> : IRepository<T> where T : class 
{ 
    protected readonly DbContext Context; 
    protected DbSet<T> DbSet; 

    public Repository(ApplicationDbContext context) 
    { 
     Context = context; 
     DbSet = context.Set<T>(); 
    } 

    public void Add(T entity) 
    { 
     Context.Set<T>().Add(entity); 

     Save(); 
    } 

    public T Get<TKey>(TKey id) 
    { 
     return DbSet.Find(id); 
    } 

    public IQueryable<T> GetAll() 
    { 
     return DbSet; 
    } 

    public void Update(T entity) 
    { 
     Save(); 
    } 

    private void Save() 
    { 
     Context.SaveChanges(); 
    } 
} 
} 

マイApplicationDbContextクラス:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) 
     : base(options) 
    { 
    } 

    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 
     // Customize the ASP.NET Identity model and override the defaults if needed. 
     // For example, you can rename the ASP.NET Identity table names and more. 
     // Add your customizations after calling base.OnModelCreating(builder); 
    } 
} 
+2

なぜ責任を混ぜるのですか?リポジトリは、データを取得する責任があります。認証はリポジトリの責任ではありません。それにはIAuthenticationFilterのようなものを使用し、それをコントローラーやアクションに適用する必要があります。リポジトリを呼び出すときには、そのユーザには承認されている必要があります –

+0

認証を処理するための好ましい方法は、そのままにして、残りのデータに汎用リポジトリを使用することです。 私はちょうど1屋根の下でそれをすべて手に入れようとしていた。 –

+1

@MarcusS:あなたは理論的にそうすることができる。パスワードを取得するなどのために、すべての機能を備えた独自のIUserStoreを実装する必要があります(https://github.com/aspnet/Identity/blob/rel/1.1.0/src/Microsoft.AspNetCoreのEF実装を参照してください)。 .Identity.EntityFrameworkCore/UserStore.cs#L161-L170)、https://github.com/aspnet/Identity/blob/rel/1.1.0/src/Microsoft.AspNetCore.Identity.EntityFrameworkCore/IdentityEntityFrameworkBuilderExtensionsに登録してください。 cs#L45-L51。あなたがEF /既知のプロバイダにマップすることができないDB構造を持っていない限り、それは価値があります – Tseng

答えて

3

はい、それは可能だが、それがそうするための努力のかなりのビットです。 IUserStore、おそらくIRoleStore(インターフェイスherehere)を実装する必要があります。

このインターフェイスを実装する場合は、すべての機能インターフェイス(パスワード、2段階認証(here)、セキュリティスタンプなど)を実装する必要があります。

実装の例として、いつでもEF Core Identity providerのソースを見ることができます。 RoleStoreため

public class GenericUserStore<TUser> : IUserStore<TUser>, 
    IUserPasswordStore<TUser> where TUser : ApplicationUser 
{ 
    public GenericUserStore(IRepository<TUser> userRepo) { } 

    public Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken) 
    { 
     return userRepo.Get(userId); 
    } 

    ... 
} 

と同じ:

public abstract class UserStore<TUser, TRole, TContext, TKey, TUserClaim, TUserRole, TUserLogin, TUserToken, TRoleClaim> : 
    IUserLoginStore<TUser>, 
    IUserRoleStore<TUser>, 
    IUserClaimStore<TUser>, 
    IUserPasswordStore<TUser>, 
    IUserSecurityStampStore<TUser>, 
    IUserEmailStore<TUser>, 
    IUserLockoutStore<TUser>, 
    IUserPhoneNumberStore<TUser>, 
    IQueryableUserStore<TUser>, 
    IUserTwoFactorStore<TUser>, 
    IUserAuthenticationTokenStore<TUser> 
    where TUser : IdentityUser<TKey, TUserClaim, TUserRole, TUserLogin> 
    where TRole : IdentityRole<TKey, TUserRole, TRoleClaim> 
    where TContext : DbContext 
    where TKey : IEquatable<TKey> 
    where TUserClaim : IdentityUserClaim<TKey> 
    where TUserRole : IdentityUserRole<TKey> 
    where TUserLogin : IdentityUserLogin<TKey> 
    where TUserToken : IdentityUserToken<TKey> 
    where TRoleClaim : IdentityRoleClaim<TKey> 
{ 
    ... 
} 

このように自分のユーザーストアは次のようになります。最後に、EFプロバイダの登録を自分のものに置き換えてください(EF hereのソース)。

userStoreType = typeof(GenericUserStore<,,,>).MakeGenericType(userType, roleType, contextType, keyType); 
roleStoreType = typeof(GenericRoleStore<,,>).MakeGenericType(roleType, contextType, keyType); 

var services = new ServiceCollection(); 
services.AddScoped(
    typeof(IUserStore<>).MakeGenericType(userType), 
    userStoreType); 
services.AddScoped(
    typeof(IRoleStore<>).MakeGenericType(roleType), 
    roleStoreType); 

UserManagerなどのIDクラスでは、ユーザー/ロールストアが使用されます。しかし、EF /既知のプロバイダにマッピングできない既存のDB構造を持たない限り、それは価値があります。

関連する問題