c# - ASP.NET 5 Identity - custom SignInManager -
i have mvc 6 project (vnext) , playing around asp.net identity. in case don't want use build-in stuff uses ef (signinmanager, usermanager, userstore). have external database , want make username/password lookup , return valid cookie. started writing own classes.
public class myuser { public string id { get; set; } public string username { get; set; } public string password { get; set; } public string passwordhash { get; set; } } public class myuserstore : iuserstore<myuser>, iuserpasswordstore<myuser> { ... } in myuserstore class using hard-coded list of users store (only test purposes). , overrode methods return data hard-coded store.
public class myusermanager : usermanager<myuser> { public myusermanager( iuserstore<myuser> store, ioptions<identityoptions> optionsaccessor, ipasswordhasher<myuser> passwordhasher, ienumerable<iuservalidator<myuser>> uservalidators, ienumerable<ipasswordvalidator<myuser>> passwordvalidators, ilookupnormalizer keynormalizer, identityerrordescriber errors, ienumerable<iusertokenprovider<myuser>> tokenproviders, iloggerfactory logger, ihttpcontextaccessor contextaccessor) : base(store, optionsaccessor, passwordhasher, uservalidators, passwordvalidators, keynormalizer, errors, tokenproviders, logger, contextaccessor) { } } here made methods checkpasswordasync , verifypasswordasync return true , passwordverificationresult.success respectively test.
public class myclaimsprinciplefactory : iuserclaimsprincipalfactory<myuser> { public task<claimsprincipal> createasync(myuser user) { return task.factory.startnew(() => { var identity = new claimsidentity(); identity.addclaim(new claim(claimtypes.name, user.username)); var principle = new claimsprincipal(identity); return principle; }); } } public class mysigninmanager : signinmanager<myuser> { public mysigninmanager(myusermanager usermanager, ihttpcontextaccessor contextaccessor, iuserclaimsprincipalfactory<myuser> claimsfactory, ioptions<identityoptions> optionsaccessor = null, iloggerfactory logger = null) : base(usermanager, contextaccessor, claimsfactory, optionsaccessor, logger) { } public override task<signinresult> passwordsigninasync(string username, string password, bool ispersistent, bool shouldlockout) { // here goes external username , password if (username.tolower() == "username" && password.tolower() == "password") { return base.passwordsigninasync(username, password, ispersistent, shouldlockout); } else { return task.fromresult(signinresult.failed); } } } and hooked in startup class follows:
services.addidentity<myuser, myrole>() .adduserstore<myuserstore>() .addusermanager<myusermanager>() .adddefaulttokenproviders(); and because didn't manage create mysigninmanager object in startup code in order add di (for later injection in controllers , views), creating in myaccountcontroller.
public myaccountcontroller(ihttpcontextaccessor httpcontextaccessor, usermanager<myuser> usermanager, ioptions<identityoptions> optionsaccessor, iloggerfactory logger) { signinmanager = new mysigninmanager(usermanager myusermanager, httpcontextaccessor, new myclaimsprinciplefactory(), optionsaccessor, logger); } in mylogin action in myaccount controller calling passwordsigninasync , can see getting cookie encoded claims in (from myclaimsprinciplefactory). when try call other action authorizeattribute on can see cookie in request header unauthorized (more precisely, because didn't remove built-in default asp.net identity authentication visual studio sample template, redirected account/login instead).
is right way of customizing asp.net identity , missing here?
in project have working implementation of identity without using ef. think maybe implementing more need to. usermanager , signinmanager not tied ef. can implement if want don't have away ef. need implement userstore , rolestore , maybe passwordhasher if needing validate hard coded password testing.
services.tryadd(servicedescriptor.scoped<iuserstore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<iuserpasswordstore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<iuseremailstore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<iuserloginstore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<iuserrolestore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<iuserclaimstore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<iuserphonenumberstore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<iuserlockoutstore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<iusertwofactorstore<siteuser>, userstore<siteuser>>()); services.tryadd(servicedescriptor.scoped<irolestore<siterole>, rolestore<siterole>>()); services.tryadd(servicedescriptor.scoped<iuserclaimsprincipalfactory<siteuser>, siteuserclaimsprincipalfactory<siteuser, siterole>>()); services.tryadd(servicedescriptor.transient<ipasswordhasher<siteuser>, sitepasswordhasher<siteuser>>()); services.addidentity<siteuser, siterole>(); the above shows items implementing bypass entity framework, accountcontroller example takes constructor parameters for
usermanager<siteuser> usermanager, signinmanager<siteuser> signinmanager which standard identity usermanager , signinmanager did not have setup di services registered me line:
services.addidentity<siteuser, siterole>(); you can see code extension method here. part of identity not part of efidentity. can see implemented iuserclaimsprincipalfactory. reason implemented add custom claims, did not need away ef.
Comments
Post a Comment