ASP.NET Custom Authentication Service + OWIN или ASP.NET Identity 2.0?

Добрый день! Прошу помощи в вопросе построения авторизации/аутентификации в N-Layer приложении.

В приложении используется трехуровневая архитектура:
  • DAL - Data Access Level (Class Library) : (Entities, Repositories, UnitOfWork)
  • BLL - Business Logic Layer (Class Library) : (DTO, Services)
  • WEB(UI) - Presentation Layer (ASP.NET MVC 5) : (ViewModels, Controllers)


Задача: необходимо сделать аутентификацию и авторизацию.

Я честно потратил два дня на изучение ASP.NET Identity 2.0, поковырял, попробовал разные варианты.
На метаните даже есть пример использования ASP.NET Identity в многоуровневой архитектуре.
Но в конечном итоге я пришел к тому, что разнося ASP.NET Identity по разным слоям и подключая зависимости,
получается какая-то каша, и вся структура приложения выглядит неудачно и не очень удобной.
Так, появляется много непонятных зависимостей, например мне требуется использовать метод GeneratePasswordResetToken, что логично сделать в собственном сервисе UsersService, в котором вызвать вышеуказанный метод. Но он тянет за собой инициализацию UserTokenProvider, который реализуется с помощью OWIN.

В итоге получается, что ASP.NET Identity + части OWIN (Security) накладываются на все слои приложения, причем делает это очень не аккуратно.
Поэтому я стал смотреть в сторону реализации собственного сервиса UsersService с теми методами, которые мне нужны, и реализовать этот сервис точно также как и реализованы все сервисы в разрабатываемом приложении.

План:

[слой DAL]
К тому же, для выполнения задачи мне нужен всего-то простые таблицы Users (UserId, Firstname, Surname, Email, Gender, e.t.c), Roles (RoleId, RoleName) и UserRoles (UserId, RoleId) для связи.
Все это я могу создать как обычные сущности и работать с ними уже по привычной модели Entities -> DTO -> ViewModel и т.п.

[слой BLL]
Что касается самого сервиса UsersService , то предпологаются базовые методы:
(Все методы очень примерные, я пытаюсь донести суть своего замешательства)

- IEnumerable GetUsers(/*Фильтр*/);
- UserDTO CreateUser(UserDTO user);
- UserDTO GetUser(int userId);
- UserDTO GetUser(string email, string password);
- void UpdateUser(UserDTO user);
- void RemoveUser(int userId);
- void ResetPassword(int userId);
- bool CheckResetPassword(int userid, string code);
- bool IsUserInRole(int userId, string roleName);
...
и тому подобные (все эти методы встречаются и в ASP.NET Identity, и в любой другой библиотеке авторизации).

[слой WEB]
Сам OWIN мне понравился и если использовать его только в одном месте, то выглядит это здорово. Поэтому в слое WEB я бы подключил OWIN + все зависимости и использовал бы авторизацию с кукисами и Claims. Claims мне нужны будут, чтобы как раз записать в кукисы UserFullname и всякие такие данные для отображения во View.

В конце-концов получится свой провайдер пользователей в виде UsersService + OWIN на WEB.

Основные вопросы:

1. Все ли будет достаточно безопасно, если все реализовать таким способом? (что касается генерации хэша пароля, то я возьму генерацию из ASP.NET Identity, она доступна тут).

2. Есть ли важные моменты, которые я упустил, и ASP.NET Identity по любому будет лучше моего решения? (если не считать времени потраченного на реализацию сервиса UsersService).

Очень нужна консультация в этих вопросах!
Заранее благодарю за любую помощь!
  • Вопрос задан
  • 1390 просмотров
Решения вопроса 1
artem_b89
@artem_b89
Сетевой бездельник
1) Достаточно
2) В Identity реализован базовый функционал работы с пользователями/ролями и т.д., возможность подключения авторизации через стороннии сервисы.
Если нужна простейшая аутентификация/авторизация, то Identity в целом не нужен, достаточно будет найти в DAL пользователя с указанными логином и паролем и авторизовать его.
Псевдокод:
public User Validate(string login, string secret)
{
  return DbContext.Users.FirstOrDefault(x=>x.login == login && secret == secret );
}  
public async void SignIn(User user)
{
	List<Claim> claims = new List<Claim>();	
	claims.Add(new Claim(ClaimTypes.Name, user.Name));
	ClaimsIdentity identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
	ClaimsPrincipal principal = new ClaimsPrincipal(identity);
	await HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
}
public async void SignOut()
{
  await HttpContext.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}

Вся остальная логика работы с пользователями и ролями пишется достаточно легко. Вопрос только в том нужно ли городить свой велосипед.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы