WebApi ASP.NET Identity Facebook login native -
basically followed answer questions: webapi asp.net identity facebook login
i'm using native ios8 facebook sdk receive fb access token, send api/account/facebooklogin , managed create user, add claims etc. , validate fb token against graph api. cant signin user token produced in facebooklogin method ...
here's code moment:
api/accountcontroller.cs
// post api/account/facebooklogin [httppost] [allowanonymous] [route("facebooklogin")] public async task<ihttpactionresult> facebooklogin([frombody] facebookloginmodel model) { if (!modelstate.isvalid) { return badrequest(modelstate); } if (string.isnullorempty(model.token)) { return badrequest("no access token"); } var tokenexpirationtimespan = timespan.fromdays(14); applicationuser user = null; string username; // fb access token , make graph call /me endpoint var fbuser = await verifyfacebookaccesstoken(model.token); if (fbuser == null) { return badrequest("invalid oauth access token"); } userlogininfo logininfo = new userlogininfo("facebook", model.userid); user = await usermanager.findasync(logininfo); // if user not found, register him username. if (user == null) { if (string.isnullorempty(model.username)) return badrequest("unregistered user"); user = new applicationuser { username = model.username, firstname = model.firstname, lastname = model.lastname, email = model.username, }; var result = await usermanager.createasync(user); if (result.succeeded) { result = await usermanager.addloginasync(user.id, logininfo); username = model.username; if (!result.succeeded) return badrequest("cannot add facebook login"); } else { return badrequest("cannot create user"); } } else { // existed user. username = user.username; } // common process: facebook claims update, login token generation user = await usermanager.findbynameasync(username); // optional: make email address confirmed when user logged in facebook. user.email = fbuser.email; user.emailconfirmed = true; await usermanager.updateasync(user); // sign-in user using owin flow //var identity = new claimsidentity(startup.oauthbeareroptions.authenticationtype); var claims = await usermanager.getclaimsasync(user.id); var newclaim = new claim("facebookaccesstoken", model.token); // compatibility asp.net mvc accountcontroller var oldclaim = claims.firstordefault(c => c.type.equals("facebookaccesstoken")); if (oldclaim == null) { var claimresult = await usermanager.addclaimasync(user.id, newclaim); if (!claimresult.succeeded) return badrequest("cannot add claims"); } else { await usermanager.removeclaimasync(user.id, oldclaim); await usermanager.addclaimasync(user.id, newclaim); } claimsidentity oauthidentity = await user.generateuseridentityasync(usermanager, oauthdefaults.authenticationtype); var currentutc = new microsoft.owin.infrastructure.systemclock().utcnow; authenticationproperties properties = applicationoauthprovider.createproperties(user.username); properties.issuedutc = currentutc; properties.expiresutc = currentutc.add(tokenexpirationtimespan); authenticationticket ticket = new authenticationticket(oauthidentity, properties); var accesstoken = startup.oauthoptions.accesstokenformat.protect(ticket); request.headers.authorization = new system.net.http.headers.authenticationheadervalue("bearer", accesstoken); authentication.signin(oauthidentity); // create response building json object mimics 1 issued default /token endpoint jobject blob = new jobject( new jproperty("username", user.username), new jproperty("userid", user.id), new jproperty("access_token", accesstoken), new jproperty("token_type", "bearer"), new jproperty("expires_in", tokenexpirationtimespan.totalseconds.tostring()), new jproperty(".issued", ticket.properties.issuedutc.tostring()), new jproperty(".expires", ticket.properties.expiresutc.tostring()), new jproperty("facebook.token", model.token) ); // return ok return ok(blob); }
startup.auth.cs
public void configureauth(iappbuilder app) { // configure db context , user manager use single instance per request app.createperowincontext(applicationdbcontext.create); app.createperowincontext<applicationusermanager>(applicationusermanager.create); // enable application use cookie store information signed in user // , use cookie temporarily store information user logging in third party login provider app.usecookieauthentication(new cookieauthenticationoptions()); app.useexternalsignincookie(defaultauthenticationtypes.externalcookie); // configure application oauth based flow publicclientid = "self"; oauthoptions = new oauthauthorizationserveroptions { tokenendpointpath = new pathstring("/token"), provider = new applicationoauthprovider(publicclientid), authorizeendpointpath = new pathstring("/api/account/externallogin"), accesstokenexpiretimespan = timespan.fromdays(14), allowinsecurehttp = true }; oauthbeareroptions = new oauthbearerauthenticationoptions(); oauthbeareroptions.accesstokenformat = oauthoptions.accesstokenformat; oauthbeareroptions.accesstokenprovider = oauthoptions.accesstokenprovider; oauthbeareroptions.authenticationmode = oauthoptions.authenticationmode; oauthbeareroptions.authenticationtype = oauthoptions.authenticationtype; oauthbeareroptions.description = oauthoptions.description; oauthbeareroptions.provider = new custombearerauthenticationprovider(); oauthbeareroptions.systemclock = oauthoptions.systemclock; // enable application use bearer tokens authenticate users app.useoauthbearertokens(oauthoptions); app.useoauthbearerauthentication(oauthbeareroptions); oauthbearerauthenticationextensions.useoauthbearerauthentication(app, oauthbeareroptions); app.usefacebookauthentication( appid: "****", appsecret: "****"); } } public class custombearerauthenticationprovider : oauthbearerauthenticationprovider { // validates identity based on issuer of claim. // issuer set in api endpoint logs user in public override task validateidentity(oauthvalidateidentitycontext context) { var claims = context.ticket.identity.claims; if( claims.count() == 0 || !claims.any(claim => claim.type == "facebookaccesstoken")) // if (!claims.any() || claims.any(claim => claim.type != "facebookaccesstoken")) // modify claim name context.rejected(); return task.fromresult<object>(null); } }
use createidentityasync
method usermanager
class instead of creating claimsidentity
yourself.
for instance, in applicationoauthprovider
generated class in method grantresourceownercredentials
following code:
claimsidentity oauthidentity = await user.generateuseridentityasync(usermanager, oauthdefaults.authenticationtype); claimsidentity cookiesidentity = await user.generateuseridentityasync(usermanager, cookieauthenticationdefaults.authenticationtype); authenticationproperties properties = await createproperties(user); authenticationticket ticket = new authenticationticket(oauthidentity, properties);
Comments
Post a Comment