public async Task <IActionResult> Token(string code, string state, string error, string encoded) { WebCache_OAuthData enc; try { string normalbase64 = encoded.Replace("-", "+").Replace("_", "/"); //Convert BASE64URL to normal Base64 int mod = normalbase64.Length % 4; if (mod == 2) { normalbase64 += "=="; } else if (mod == 3) { normalbase64 += "="; } enc = JsonConvert.DeserializeObject <WebCache_OAuthData>(Encoding.UTF8.GetString(Convert.FromBase64String(normalbase64))); if (enc == null) //Bad encoded data, no way to redirect the error { return(StatusCode(400, "Bad Request")); } } catch (Exception e) //Bad encoded data, no way to redirect the error { _logger.LogError(e, "OAuth Token Error: Bad encoded data."); return(StatusCode(400, "Bad Request")); } WebCache_OAuthAccessTokenWithState errtoken = new WebCache_OAuthAccessTokenWithState(); SessionInfoWithError s = await VerifyTokenAsync(enc.Token); if (s.Error != null) { errtoken.error = s.Error.StatusCode + ": " + s.Error; return(ReturnResult(enc, errtoken)); } Dictionary <string, Credentials> providers = GetOAuthProviders(); if (!providers.ContainsKey(enc.Provider)) { errtoken.error = $"404: Provider {enc.Provider} Not Found"; _logger.LogError($"Provider {enc.Provider} Not Found"); return(ReturnResult(enc, errtoken)); } Credentials credentials = providers[enc.Provider]; var token = await GetTokenAsync(code, state, credentials, enc.OriginalRedirectUri); if (token == null) { errtoken.error = "400: Bad Request"; return(ReturnResult(enc, errtoken)); } return(ReturnResult(enc, token)); }
private IActionResult ReturnResult(WebCache_OAuthData enc, WebCache_OAuthAccessTokenWithState token) { //If the encoded data has a redirect back, lets redirect the page, //otherwise return a web page, with the access token in a head meta tag if (enc.RedirectUri != null) { string separator = "?"; if (enc.RedirectUri.Contains("?")) { separator = "&"; } return(Redirect(enc.RedirectUri + separator + token.GetQueryString())); } string json = JsonConvert.SerializeObject(token, Formatting.None).Replace("\r", "").Replace("\n", ""); return(new ContentResult { ContentType = "text/html", StatusCode = (int)HttpStatusCode.OK, Content = "<html><head><meta name=\"AccessToken\" content=\"" + HttpUtility.HtmlEncode(json) + "\"/></head></html>" }); }
private async Task <WebCache_OAuthAccessTokenWithState> GetTokenAsync(string code, string state, Credentials credentials, string redirecturi) { try { Dictionary <string, string> postdata = new Dictionary <string, string>(); postdata.Add("grant_type", "authorization_code"); postdata.Add("code", code); postdata.Add("client_id", credentials.Id); postdata.Add("client_secret", credentials.Secret); postdata.Add("redirect_uri", redirecturi); using (var client = new HttpClient()) { string accept = "application/json"; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, credentials.TokenUri); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(accept)); request.Content = new FormUrlEncodedContent(postdata); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded"); HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead); if (!response.IsSuccessStatusCode) { _logger.LogError($"Unable to get token from provider at {credentials.TokenUri}, Status Code: {response.StatusCode} Error: {response.ReasonPhrase ?? "None"}"); return(null); } WebCache_OAuthAccessTokenWithState at = JsonConvert.DeserializeObject <WebCache_OAuthAccessTokenWithState>(await response.Content.ReadAsStringAsync()); at.state = state; return(at); } } catch (Exception e) { _logger.LogError(e, $"Unable to get token from provider at {credentials.TokenUri} Exception caught"); return(null); } }
public static string GetQueryString(this WebCache_OAuthAccessTokenWithState at) => "access_token=" + HttpUtility.UrlEncode(at.access_token) + "&token_type=" + HttpUtility.UrlEncode(at.token_type) + "&expires_in=" + HttpUtility.UrlEncode(at.expires_in.ToString()) + "&state=" + HttpUtility.UrlEncode(at.state);