angularjs - refresh token with bearer token authentication on asp.net vnext -


i have angularjs application uses asp.net vnext authenticates using jwtbearerauthentication. authenticate application use aspnet.security.openidconnect.server. when login, receive json response contains access_token can use authorized requests. like, receive refresh token. how possible?

startup.cs

public void configure(iapplicationbuilder app) {     app.usejwtbearerauthentication(options => {         options.automaticauthenticate = true;         options.automaticchallenge = true;         options.tokenvalidationparameters.validateaudience = false;         options.authority = configuration.get<string>("oauth:authority");         options.configurationmanager = new configurationmanager<openidconnectconfiguration>(             metadataaddress: options.authority + ".well-known/openid-configuration",             configretriever: new openidconnectconfigurationretriever(),             docretriever: new httpdocumentretriever() { requirehttps = false });     });      app.useopenidconnectserver(configuration => {         configuration.issuer = new uri(configuration.get<string>("openid:issuer"));         configuration.allowinsecurehttp = true;         configuration.authorizationendpointpath = pathstring.empty;         configuration.authenticationscheme = openidconnectserverdefaults.authenticationscheme;         configuration.provider = new authorizationprovider();     }); } 

authorizationprovider.cs

public class authorizationprovider : openidconnectserverprovider {     public override task validateclientauthentication(validateclientauthenticationcontext context) {         context.skipped();          return task.fromresult<object>(null);     }      public override task grantresourceownercredentials(grantresourceownercredentialscontext context) {         string username = context.username;         string password = context.password;          usermanager<applicationuser> usermanager = context.httpcontext.requestservices.getrequiredservice<usermanager<applicationuser>>();         applicationuser user = usermanager.findbynameasync(username).result;          if (usermanager.checkpasswordasync(user, password).result) {             claimsidentity identity = new claimsidentity(openidconnectserverdefaults.authenticationscheme);             identity.addclaim(claimtypes.name, username, "token id_token");              list<string> roles = usermanager.getrolesasync(user).result.tolist();             foreach (string role in roles) {                 identity.addclaim(claimtypes.role, role, "token id_token");             }              claimsprincipal principal = new claimsprincipal(identity);             context.validated(principal);         } else {             context.rejected("invalid credentials");         }          return task.fromresult<object>(null);     } } 

angularjs login code

$http({     method: 'post',     url: 'connect/token',     headers: {         'content-type': 'application/x-www-form-urlencoded; charset=utf-8'     },     data: $.param({         grant_type: 'password',         username: email,         password: password     }) }).then(function (response) {     if (response.status == 200) {         var token = response.data.access_token;         localstorage.setitem('token', token);     } }); 

unlike oauthauthorizationservermiddleware, asos offers built-in support refresh tokens: don't have create own token provider that.

note starting asos beta3 (released in october 2015), have ask , grant offline_access scope retrieve refresh token, as recommended openid connect specs: https://github.com/aspnet-contrib/aspnet.security.openidconnect.server/issues/128

you'll need update grantresourceownercredentials allow asos issue refresh token client application:

public override async task grantresourceownercredentials(grantresourceownercredentialscontext context) {     string username = context.username;     string password = context.password;      usermanager<applicationuser> usermanager = context.httpcontext.requestservices.getrequiredservice<usermanager<applicationuser>>();     applicationuser user = await usermanager.findbynameasync(username);      if (await usermanager.checkpasswordasync(user, password)) {         claimsidentity identity = new claimsidentity(             context.options.authenticationscheme);          identity.addclaim(claimtypes.name, username,             openidconnectconstants.destinations.accesstoken,             openidconnectconstants.destinations.identitytoken);          foreach (string role in await usermanager.getrolesasync(user)) {             identity.addclaim(claimtypes.role, role,                 openidconnectconstants.destinations.accesstoken,                 openidconnectconstants.destinations.identitytoken);         }          authenticationticket ticket = new authenticationticket(             new claimsprincipal(identity),             new authenticationproperties(),             context.options.authenticationscheme);          // call setresources list of resource servers         // access token should issued for.         ticket.setresources("resource_server_1");          // grant "offline_access" scope         // if requested client application:         list<string> scopes = new list<string>();         if (context.request.hasscope("offline_access")) {             scopes.add("offline_access");         }          // call setscopes list of scopes want grant.         ticket.setscopes(scopes);          context.validate(ticket);     } else {         context.reject("invalid credentials");     }      return task.fromresult(0); } 

... , angular code specify scope parameter:

$http({     method: 'post',     url: 'connect/token',     headers: {         'content-type': 'application/x-www-form-urlencoded; charset=utf-8'     },     data: $.param({         grant_type: 'password',         username: email,         password: password,         scope: 'offline_access'     }) }).then(function (response) {     if (response.status == 200) {         var token = response.data.access_token;         var refreshtoken = response.data.refresh_token;         localstorage.setitem('token', token);         localstorage.setitem('refresh_token', refreshtoken);     } }); 

to retrieve new access token, use refresh_token grant:

$http({     method: 'post',     url: 'connect/token',     headers: {         'content-type': 'application/x-www-form-urlencoded; charset=utf-8'     },     data: $.param({         grant_type: 'refresh_token',         refresh_token: refreshtoken     }) }).then(function (response) {     if (response.status == 200) {         var token = response.data.access_token;         localstorage.setitem('token', token);     } }); 

Comments