Я работаю над веб-API и не уверен, что совершил ошибку, отказавшись от использования системы членства Identity
и внедрив собственную настройку аутентификации.
Из того, что я читал, похоже, что это отличное решение для внешнего входа в систему, такого как Facebook, где вы можете использовать UserManager
, чтобы легко коммитить различные CRUD для пользователей и т. д., но я также видел, что это используется другими людьми для их веб-сайтов. API.
Я избегал его не только из-за верхнего абзаца, но и из-за следующей выдержки из этого официального документ.
Identity is enabled for the application by calling UseIdentity in the Configure method of the Startup class. This adds cookie-based authentication to the request pipeline.
Это может показаться странным, но зачем мне аутентификация на основе файлов cookie для веб-API? Мне удалось защитить его с помощью пользовательских таблиц Login/Claims и JWT Bearer Authentication, и вот как я это сделал.
Вот как мне удалось реализовать пользовательские таблицы User/Claim.
Таблица UserIdentity (уменьшенная версия таблиц AspNetUsers из контейнера Identity)
public class UserIdentity
{
public Guid Id { get; set; }
public string Username { get; set; }
public string HashPassword { get; set; }
}
Утверждения пользователей (уменьшенная версия AspNetUserClaims)
public class UserClaims
{
public Guid Id { get; set; }
public string ClaimType { get; set; }
public string ClaimValue { get; set; }
[Required]
public virtual UserIdentity UserIdentity { get; set; }
}
Это мой DbContext (обратите внимание, что я использовал DbContext
вместо IdentityDbContext
)
public class CustomContext : DbContext
{
public CustomContext(DbContextOptions<CustomContext> options)
: base(options)
{
}
public DbSet<UserIdentity> Users { get; set; }
public DbSet<UserClaims> UserClaims { get; set; }
// other custom DSets...
....
}
И мой контроллер JWT
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Get([FromForm] ApplicationUser applicationUser)
{
var identity = await GetClaimsIdentity(applicationUser, _customContext);
if (identity == null)
{
_logger.LogInformation($"Invalid username ({applicationUser.UserName}) or password ({applicationUser.Password})");
return BadRequest("Invalid credentials");
}
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, applicationUser.UserName),
new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(), ClaimValueTypes.Integer64),
//identity.FindFirst("Diamond")
identity.Claims.Last()
};
А в GetClaimsIdentity я просто получаю все претензии пользователя из переданного экземпляра DbContext из контроллера CTOR
.
private static Task<ClaimsIdentity> GetClaimsIdentity(ApplicationUser user, CustomContext customContext)
{
var currentUser = partnerContext.Users.FirstOrDefault(x => x.HashPassword == user.Password && x.Username == user.UserName);
if (currentUser != null)
{
//Getting the user claims
var listOfClaims =
from claim in partnerContext.UserClaims.Where(x => x.UserIdentity.Id == currentUser.Id)
select new Claim(claim.ClaimType, claim.ClaimValue);
if (!listOfClaims.Any())
return Task.FromResult<ClaimsIdentity>(null);
return Task.FromResult(new ClaimsIdentity(new GenericIdentity(user.UserName, "Token"),
listOfClaims));
}
return Task.FromResult<ClaimsIdentity>(null);
}
Этот подход работает, но он немного смущает меня, правильно ли я сделал выбор, отказавшись от IdentityDbContext
только из-за возможности «аутентификации на основе файлов cookie».
Я также читал о настройке вашего собственного Пользовательские хранилища, но в итоге у меня возникло такое же сомнение, зачем мне нужна "аутентификация файлов cookie", что мне не хватает?
UseIdentity()
? Должна быть возможность добавить службы идентификацииservices.AddIdentity(...)
в методConfigureServices
, а затем не добавлять идентификацию в конвейер. - person Brad   schedule 05.10.2016