Identyfikacja ASP.NET jest nieco zbyt skomplikowana, powiedziałbym.
W sierpniu 2014 r. Ogłosili nową wersję 2.1, a sytuacja znów się zmieniła.
Przede wszystkim niech pozbyć EntityFramework
:
Uninstall-Package Microsoft.AspNet.Identity.EntityFramework
Teraz możemy realizować naszą własną definicję User
wykonawczych interfejs IUser
(Microsoft.AspNet.Identity):
public class User: IUser<int>
{
public User()
{
this.Roles = new List<string>();
this.Claims = new List<UserClaim>();
}
public User(string userName)
: this()
{
this.UserName = userName;
}
public User(int id, string userName): this()
{
this.Id = Id;
this.UserName = userName;
}
public int Id { get; set; }
public string UserName { get; set; }
public string PasswordHash { get; set; }
public bool LockoutEnabled { get; set; }
public DateTime? LockoutEndDateUtc { get; set; }
public bool TwoFactorEnabled { get; set; }
public IList<string> Roles { get; private set; }
public IList<UserClaim> Claims { get; private set; }
}
jak można zobacz Mam zdefiniowany typ mojego Id
(int).
Następnie należy zdefiniować niestandardowe UserManager
dziedzicząc po Microsoft.AspNet.Identity.UserManager
, określając typ użytkownika i typ klucza.
public class UserManager : UserManager<User, int>
{
public UserManager(IUserStore<User, int> store): base(store)
{
this.UserLockoutEnabledByDefault = false;
// this.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(10);
// this.MaxFailedAccessAttemptsBeforeLockout = 10;
this.UserValidator = new UserValidator<User, int>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = false
};
// Configure validation logic for passwords
this.PasswordValidator = new PasswordValidator
{
RequiredLength = 4,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
}
}
I zostały wdrożone moje zasady weryfikacji tutaj, ale można zachować go na zewnątrz, jeśli wolisz.
UserManager
potrzebuje UserStore
(IUserStore).
Tutaj zdefiniujesz swoją logikę DB. Istnieje kilka interfejsów do wdrożenia. Nie wszystkie z nich są jednak obowiązkowe.
public class UserStore :
IUserStore<User, int>,
IUserPasswordStore<User, int>,
IUserLockoutStore<User, int>,
IUserTwoFactorStore<User, int>,
IUserRoleStore<User, int>,
IUserClaimStore<User, int>
{
// You can inject connection string or db session
public UserStore()
{
}
}
Nie uwzględniłem wszystkich metod dla każdego interfejsu. Kiedy już to zrobisz, że będziesz w stanie napisać nowego użytkownika:
public System.Threading.Tasks.Task CreateAsync(User user)
{
}
sprowadzić go przez ID:
public System.Threading.Tasks.Task<User> FindByIdAsync(int userId)
{
}
i tak dalej.
Następnie musisz zdefiniować swoją SignInManager
dziedzicząc po Microsoft.AspNet.Identity.Owin.SignInManager
.
public class SignInManager: SignInManager<User, int>
{
public SignInManager(UserManager userManager, IAuthenticationManager authenticationManager): base(userManager, authenticationManager)
{
}
public override Task SignInAsync(User user, bool isPersistent, bool rememberBrowser)
{
return base.SignInAsync(user, isPersistent, rememberBrowser);
}
}
mam tylko realizowane SignInAsync
: To generuje ClaimsIdentity.
To wszystko.
Teraz w klasie Startup
musisz powiedzieć Owin
, jak utworzyć UserManager
i SignInManager
.
app.CreatePerOwinContext<Custom.Identity.UserManager>(() => new Custom.Identity.UserManager(new Custom.Identity.UserStore()));
// app.CreatePerOwinContext<Custom.Identity.RoleManager>(() => new Custom.Identity.RoleManager(new Custom.Identity.RoleStore()));
app.CreatePerOwinContext<Custom.Identity.SignInService>((options, context) => new Custom.Identity.SignInService(context.GetUserManager<Custom.Identity.UserManager>(), context.Authentication));
Nie używałem fabryki znajdą Państwo w domyślnym szablonie bo chciał zachować rzeczy tak proste, jak to możliwe.
i umożliwić aplikacji do korzystania z cookies:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<Custom.Identity.UserManager, Custom.Identity.User, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: (manager, user) =>
{
var userIdentity = manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
return (userIdentity);
},
getUserIdCallback: (id) => (Int32.Parse(id.GetUserId()))
)}
});
Teraz w kontrolerze konta - lub kontrolera odpowiedzialnego za logowania - trzeba będzie uzyskać UserManager
i SignInManager
:
public Custom.Identity.SignInManager SignInManager
{
get
{
return HttpContext.GetOwinContext().Get<Custom.Identity.SignInManager>();
}
}
public Custom.Identity.UserManager UserManager
{
get
{
return HttpContext.GetOwinContext().GetUserManager<Custom.Identity.UserManager>();
}
}
Będziesz używać SignInManager
do logowania:
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
i UserManager
stworzyć użytkownika, dodawanie ról i roszczeń:
if (ModelState.IsValid)
{
var user = new Custom.Identity.User() { UserName = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
// await UserManager.AddToRoleAsync(user.Id, "Administrators");
// await UserManager.AddClaimAsync(user.Id, new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Country, "England"));
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
Wydaje się komplikować ... i to jest ... rodzaju.
Jeśli chcesz przeczytać więcej na ten temat, istnieje dobre wyjaśnienie: here i here.
Jeśli chcesz uruchomić kod i zobaczyć, jak to działa, przygotowałem dla ciebie code, który działa z Biggy (ponieważ nie chciałem tracić czasu na definiowanie tabel i podobnych rzeczy).
Jeśli masz szansę pobrać mój kod z repozytorium github, zauważysz, że utworzyłem projekt wtórny (Custom.Identity), w którym przechowywałem wszystkie moje rzeczy związane z ASP.NET Identity.
Jedynym Nuget pakiety będą potrzebne są:
- Microsoft.AspNet.Identity.Core
- Microsoft.AspNet.Identity.Owin
Tak można dostosować sposób UserManager zachowuje się. Sposób uzyskiwania danych odbywa się poprzez implementację 'IUserStore'. Oto odpowiedź, która może Ci pomóc w dostosowaniu tego. http://stackoverflow.com/questions/19940014/asp-net-identity-with-ef-database-first-mvc5/21122865#21122865 – Shoe