15

Я вот-вот начну с проекта, где буду использовать MVC5. Но поскольку я хочу использовать IoC, а затем повторно использовать мои пользовательские таблицы и добавлять к ним настраиваемые материалы, мне очень сложно понять, как я могу использовать новую структуру Identity, которая поставляется с MVC5.MVC 5 IoC и аутентификация

Я все больше и больше смотрю на основные формы auth. Каковы ваши решения?

Мои потребности:

  • хранилище пользователя/услуга должна быть введена
  • хранилище Пользователь должен находиться в DAL
  • хранилище Пользователь должен иметь возможность поддерживать другие технологии, чем EF
  • аутентификации с помощью OpenID и OAuth должно быть несколько легким в использовании.
  • ДОЛЖНО БЫТЬ БЕЗОПАСНО
  • Должно быть многоразовым в другом проектов, например. WPF

Я долго искал ответ, но все, что я вижу, жестко закодировано в контроллере.

Как вы решаете это? Вы пишете больше всего с нуля или можете привязываться к чему-то, что будет масштабироваться для других платформ .NET, как WCF и WPF?

Приведенный ниже код берется непосредственно из AccountController в шаблоне ASP.NET MVC 5 по умолчанию. Первое, что он делает, это Bastard Injection.

[Authorize] 
public class AccountController : Controller 
{ 
    public AccountController() 
     : this(
      new UserManager<ApplicationUser>(
       new UserStore<ApplicationUser>(
        new ApplicationDbContext()))) 
    { 
    } 

    public AccountController(UserManager<ApplicationUser> userManager) 
    { 
     UserManager = userManager; 
    } 
} 

Принятая ответ будет идти к человеку, который показывает мне, что они сделали, что включает в себя вышеуказанные требования

+0

Похожие: http://stackoverflow.com/a/2092156/126014 –

+0

@MarkSeemann Спасибо за ссылку. Однако я пропускаю немного больше информации. Я вижу суть, но я хочу знать, как я могу реализовать решение, которое я могу масштабировать. Например. Я не хочу, чтобы пароль пользователя использовался только на этом веб-сайте. Знаете ли вы какие-либо ресурсы, которые я могу изучить, чтобы получить необходимую гибкость. –

+0

Связанный: http://stackoverflow.com/q/1979627/126014 –

ответ

3

В итоге я решил реализовать IUserStore, IUserStore, IUserPasswordStore, IUserLoginStore, чтобы переместить UserRepository в его законное место - уровень DataAccess. Но все равно получите Бенифиты безопасности Owin и новую систему Identity Framework.

Это довольно просто реализовать, и не нужно много абстрагировать его. Вот вкус UserStoreWrapper

namespace qubis.booking.WebApp.App_Code.Identity 
{ 
    public class UserServiceWrapper : IUserStore<ApplicationUserWrapper>, 
             IUserPasswordStore<ApplicationUserWrapper>, 
             IUserLoginStore<ApplicationUserWrapper> 
    { 
     public IUserRepository UserRepos { get; set; } // My own Interface. 
     public UserServiceWrapper(IUserRepository userRepo) 
     { 
      UserRepos = userRepo; 
     } 


     public async Task CreateAsync(ApplicationUserWrapper user) 
     { 
      UserRepos.Insert(user.RealUser); 
     } 

     public async Task<ApplicationUserWrapper> FindByIdAsync(string userId) 
     { 
      var appUser = UserRepos.FindByUserName(userId); 
      ApplicationUserWrapper wrappedUser; 
      if (appUser != null) 
      { 
       wrappedUser = new ApplicationUserWrapper(appUser); 
      } 
      else 
       wrappedUser = null; 
      return wrappedUser; 
     } 

В контроллере Account я просто просто попросить, чтобы он был введен:

public AccountController(UserManager<ApplicationUserWrapper> userManager) 
{ 
    UserManager = userManager;{ AllowOnlyAlphanumericUserNames = false }; 
} 

И как я использую Ninject Я просто установить его UPIN ядро, как так :

// <summary> 
// Load your modules or register your services here! 
// </summary> 
// <param name="kernel">The kernel.</param> 
private static void RegisterServices(IKernel kernel) 
{ 
    kernel.Bind<IUserStore<ApplicationUserWrapper>>().To<UserServiceWrapper>(); 
    kernel.Bind<UserManager<ApplicationUserWrapper>>().ToSelf(); 
} 

Чтобы увидеть структуру фреймворка Identity, см. Эту статью. http://www.asp.net/identity/overview/extensibility/implementing-a-custom-mysql-aspnet-identity-storage-provider

+5

Что такое "ApplicationUserWrapper"? Можете ли вы поделиться полной реализацией? Как, например, как выглядит ваш AccountController после факта? Есть ли какие-либо другие проблемы, с которыми вы столкнулись после внедрения этого подхода? – Robert

+0

@ André Snede Hansen: Возможно, вы можете поделиться еще несколькими кодами? Я тоже нуждаюсь в этом разделении! – janhartmann

+0

@meep Возможно позже. –

3

Вы могли бы быть заинтересованы, чтобы взглянуть на Thinktecture.IdentityServer.v2https://github.com/thinktecture/Thinktecture.IdentityServer.v2. Многие из ваших проблем уже реализованы и инкапсулированы. Если вы не найдете то, что вам нужно, вам придется подумать о том, как абстрагировать все эти проблемы и реализовать их самостоятельно.

+1

Спасибо за ваш ответ, но я не ищу другую зависимость. Я хотел бы получить столько же, сколько предлагает ASP.NET. Между тем быть способным согнуть это по моей воле. –

+0

Я думаю, что было бы полезно посмотреть, как они справились с этим, и если вы хотите, вы можете выбрать некоторые идеи для своей собственной работы. –

+1

Я вижу вашу мысль, и я, вероятно, многому научился бы погружаться в свой код. Но я предпочел бы иметь книгу или другой ресурс, который объясняет понятия, лучшие практики и действия, почему и не нужно. –

7

Поскольку это .NET, стандартным подходом к безопасности является аутентификация на границе приложения и преобразование информации аутентификации в IPrincipal. MVC поддерживает это из коробки.

Если вам нужна другая информация, полученная в ходе аутентификации, вы можете собрать ее в Composition Root и использовать ее для составления ваших услуг.

В качестве примера представьте, что вам нужен адрес электронной почты с аутентифицированным пользователем на нижнем уровне. Любой класс, который требует адрес электронной почты пользователя может просто запросить его как Concrete Dependency:

public class EmailThingy 
{ 
    private readonly string userEmail; 

    public EmailThingy(string userEmail) 
    { 
     if (userEmail == null) 
      throw new ArgumentNullException("userEmail"); 

     this.userEmail = userEmail; 
    } 

    // other members go here... 
} 

В ASP.NET MVC, Сочинение Корневая IControllerFactory. IIRC, вы можете вытащить данные аутентификации из метода CreateController и использовать его для составления графика объекта.

В настоящее время я использую IPrincipal так же: я добавляю его как зависимость, вместо того, чтобы полагаться на Thread.CurrentPrincipal Ambient Context, потому что легче тестировать устройство, когда все последовательно вводится через Инъекция конструктора.

+0

Спасибо, Марк. Это много ответило на мои вопросы. Но можете ли вы подробнее рассказать о том, как я лучше всего использую систему аутентификации, которая может масштабироваться. Поскольку я чувствую, что новая структура Identity и UserManager в ASP.NET MVC 5 сильно зависит от EntityFramework. Все пользовательские данные и логика аутентификации (совпадающие пароли и т. Д.) - это то, что я хотел бы абстрагировать до уровня домена и DAL. Поэтому я могу повторно использовать его в приложении WCF или WPF. –

+1

Что вы подразумеваете под системой * Аутентификация *? Имя пользователя Пароль? OAuth? OpenId? Проверка подлинности Facebook? Двухфакторная? На основе утверждений? –

+0

Я хочу, чтобы иметь возможность реализовать свое собственное User Service, где я отвечаю за проверку паролей и всего, но где я могу сохранить как можно больше функциональности от MVC goodiebag. Короче говоря, я хочу иметь возможность вводить аутентификацию вместо использования настройки по умолчанию из шаблона MVC. И мне интересно, как это делают люди. Я хочу иметь возможность использовать те же механизмы аутентификации в других проектах, и даже изменить его, если я сочтую нужным в будущем. –

0

Если все, что вам нужно, чтобы впрыснуть реализация пользовательских UserStore this article may help you

В основном вам нужно впрыснуть это (зависит, если вы хотите использовать роли, претензии и т.д ..):

  1. Напишите класс пользователя, который реализует интерфейс IUser

    public class IdentityUser : IUser { 
        public IdentityUser(){...} 
        public IdentityUser(string userName)(){...} 
        public string Id { get; set; } 
        public string UserName { get; set; } 
        public string PasswordHash { get; set; } 
        public string SecurityStamp { get; set; } 
    } 
    
  2. Написать класс магазин пользователя, который реализует IUserStore, IUserClaimStore, IUserLoginStore, IUserRoleStore и IUserPasswordStore

    public class UserStore : IUserStore<IdentityUser>, 
        IUserClaimStore<IdentityUser>, 
        IUserLoginStore<IdentityUser>, 
        IUserRoleStore<IdentityUser>, 
        IUserPasswordStore<IdentityUser> { 
    
        public UserStore(){...} 
        public Task CreateAsync(IdentityUser user){...} 
        public Task<IdentityUser> FindByIdAsync(string userId){...} 
        .. . 
    } 
    
Смежные вопросы