title: How to implement refresh token workflow into OAUTH workflow in MVC C# app?
body: <p>I am new to OAUTH. I have been working on implementing OAUTH into my MVC c# application to access ping federate. After much research, and failed attempt at using the ping federate nuget, I came across this <a href="https://stackoverflow.com/questions/25845420/mvc-5-application-implement-oauth-authorization-code-flow">link</a> that finally gave some clarity to the full process with a coding example. I have came across much generic examples of the endpoints i need to access but never a full workflow coding example. After implementing that code with some changes and was successful at signing in the ping user into my MVC app, I started doing more research about the refresh token. Questions...</p>
  
  <p>Q. I know how to access a a refresh token, meaning I know which endpoint used to refresh the access token after I have authenticated the user in ping federate. But what is the refresh token used for? Is it used to extend my application's session once it ends? Or it used for if the user signs out of my application then they click the 'Sign in with Ping Federate' link on the login and not have them authenticate again as long as the refresh token is still valid?</p>
  
  <p>Q. And if the refresh token is used for when after a user authenticates the first time, and I save the refresh token in the db and then user signs back using that 'Sign in with Ping Federate' link on my login back how can I know what user that is to lookup the refresh token in the db to give them access to my site without re-authenticating them with ping federate? Since when they come to that link 'Sign in with Ping Federate' I do not know who they are?</p>
  
  <p>This is the below code that I am using, from user MatthiasRamp in the link i provided...I want to add my refresh token logic with the below code. </p>
  
  <pre><code>public async Task&lt;ActionResult&gt; Login(string returnUrl)
  {
  if (string.IsNullOrEmpty(returnUrl) &amp;&amp; Request.UrlReferrer != null)
      returnUrl = Server.UrlEncode(Request.UrlReferrer.PathAndQuery);
  
  if (Url.IsLocalUrl(returnUrl) &amp;&amp; !string.IsNullOrEmpty(returnUrl))
      _returnUrl = returnUrl;
  
  //callback function
  _redirectUrl = Url.Action("AuthorizationCodeCallback", "ExternalLogin", null, Request.Url.Scheme);
  
  Dictionary&lt;string, string&gt; authorizeArgs = null;
  authorizeArgs = new Dictionary&lt;string, string&gt;
  {
      {"client_id", "0123456789"}
      ,{"response_type", "code"}
      ,{"scope", "read"}
      ,{"redirect_uri", _redirectUrl}
      // optional: state
  };
  
  var content = new FormUrlEncodedContent(authorizeArgs);
  var contentAsString = await content.ReadAsStringAsync();
  return Redirect("http://localhost:64426/oauth/authorize?" + contentAsString);}
  
  public async Task&lt;ActionResult&gt; AuthorizationCodeCallback()
  {
  // received authorization code from authorization server
  string[] codes = Request.Params.GetValues("code");
  var authorizationCode = "";
  if (codes.Length &gt; 0)
      authorizationCode = codes[0];
  
  // exchange authorization code at authorization server for an access and refresh token
  Dictionary&lt;string, string&gt; post = null;
  post = new Dictionary&lt;string, string&gt;
  {
      {"client_id", "0123456789"}
      ,{"client_secret", "ClientSecret"}
      ,{"grant_type", "authorization_code"}
      ,{"code", authorizationCode}
      ,{"redirect_uri", _redirectUrl}
  };
  
  var client = new HttpClient();
  var postContent = new FormUrlEncodedContent(post);
  var response = await client.PostAsync("http://localhost:64426/token", postContent);
  var content = await response.Content.ReadAsStringAsync();
  
  // received tokens from authorization server
  var json = JObject.Parse(content);
  _accessToken = json["access_token"].ToString();
  _authorizationScheme = json["token_type"].ToString();
  _expiresIn = json["expires_in"].ToString();
  if (json["refresh_token"] != null)
      _refreshToken = json["refresh_token"].ToString();
  
  //SignIn with Token, SignOut and create new identity for SignIn
  Request.Headers.Add("Authorization", _authorizationScheme + " " + _accessToken);
  var ctx = Request.GetOwinContext();
  var authenticateResult = await ctx.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);
  ctx.Authentication.SignOut(DefaultAuthenticationTypes.ExternalBearer);
  var applicationCookieIdentity = new ClaimsIdentity(authenticateResult.Identity.Claims, DefaultAuthenticationTypes.ApplicationCookie);
  ctx.Authentication.SignIn(applicationCookieIdentity);
  
  var ctxUser = ctx.Authentication.User;
  var user = Request.RequestContext.HttpContext.User;
  
  //redirect back to the view which required authentication
  string decodedUrl = "";
  if (!string.IsNullOrEmpty(_returnUrl))
      decodedUrl = Server.UrlDecode(_returnUrl);
  
  if (Url.IsLocalUrl(decodedUrl))
      return Redirect(decodedUrl);
  else
      return RedirectToAction("Index", "Home");
  }
  </code></pre>