protected virtual async Task <string> GetEmailAsync([NotNull] OAuthTokenResponse tokens) { // See http://open.weibo.com/wiki/2/account/profile/email for more information about the /account/profile/email.json endpoint. string address = QueryHelpers.AddQueryString(Options.UserEmailsEndpoint, "access_token", tokens.AccessToken); using var request = new HttpRequestMessage(HttpMethod.Get, address); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogWarning("An error occurred while retrieving the email address associated with the logged in user: "******"the remote server returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync()); throw new HttpRequestException("An error occurred while retrieving the email address associated to the user profile."); } using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); return((from email in payload.RootElement.EnumerateArray() select email.GetString("email")).FirstOrDefault()); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context) { var tokenRequestParameters = new Dictionary <string, string?>() { ["app_id"] = Options.ClientId, ["secret"] = Options.ClientSecret, ["code"] = context.Code, ["output"] = "json", }; // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out string?codeVerifier)) { tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier); context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey); } string endpoint = QueryHelpers.AddQueryString(Options.TokenEndpoint, tokenRequestParameters); using var requestMessage = new HttpRequestMessage(HttpMethod.Get, endpoint); requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); using var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted); if (!response.IsSuccessStatusCode) { await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an OAuth token."))); } var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); return(OAuthTokenResponse.Success(payload)); }
/// <inheritdoc /> protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri) { var content = ToJsonContent(new { token = new { grant_type = "authorization_code", code, client_id = Options.ClientId, client_secret = Options.ClientSecret, redirect_uri = redirectUri, scope = string.Join(" ", Options.Scopes) } }); var response = await Backchannel.SendAsync(new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint) { Headers = { Accept = { new MediaTypeWithQualityHeaderValue("application/json") } }, Content = content }, Context.RequestAborted); return(response.IsSuccessStatusCode ? OAuthTokenResponse.Success(JObject.Parse(await response.Content.ReadAsStringAsync())) : OAuthTokenResponse.Failed(new Exception("OAuth token endpoint failure: " + await Display(response)))); }
protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); var response = await Backchannel.SendAsync(request, Context.RequestAborted); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"Failed to retrived Microsoft user information ({response.StatusCode}) Please check if the authentication information is correct and the corresponding Microsoft Account API is enabled."); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme); var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload); var identifier = MicrosoftAccountHelper.GetId(payload); if (!string.IsNullOrEmpty(identifier)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:microsoftaccount:id", identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } var name = MicrosoftAccountHelper.GetDisplayName(payload); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:microsoftaccount:name", name, ClaimValueTypes.String, Options.ClaimsIssuer)); } var givenName = MicrosoftAccountHelper.GetGivenName(payload); if (!string.IsNullOrEmpty(givenName)) { identity.AddClaim(new Claim(ClaimTypes.GivenName, givenName, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:microsoftaccount:givenname", givenName, ClaimValueTypes.String, Options.ClaimsIssuer)); } var surname = MicrosoftAccountHelper.GetSurname(payload); if (!string.IsNullOrEmpty(surname)) { identity.AddClaim(new Claim(ClaimTypes.Surname, surname, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:microsoftaccount:surname", surname, ClaimValueTypes.String, Options.ClaimsIssuer)); } var email = MicrosoftAccountHelper.GetEmail(payload); if (!string.IsNullOrEmpty(email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer)); } await Options.Events.CreatingTicket(context); return(context.Ticket); }
protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var endpoint = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, "access_token", tokens.AccessToken); if (Options.SendAppSecretProof) { endpoint = QueryHelpers.AddQueryString(endpoint, "appsecret_proof", GenerateAppSecretProof(tokens.AccessToken)); } if (Options.Fields.Count > 0) { endpoint = QueryHelpers.AddQueryString(endpoint, "fields", string.Join(",", Options.Fields)); } var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"Failed to retrieve Facebook user information ({response.StatusCode}) Please check if the authentication information is correct and the corresponding Facebook Graph API is enabled."); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload); context.RunClaimActions(); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
/// <inheritdoc /> protected override async Task <AuthenticationTicket> CreateTicketAsync( ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { // Get the Google user var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); var response = await Backchannel.SendAsync(request, Context.RequestAborted); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"An error occurred when retrieving Google user information ({response.StatusCode}). Please check if the authentication information is correct."); } using (var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted))) { var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); context.RunClaimActions(); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal !, context.Properties, Scheme.Name)); } }
protected override async Task <AuthenticationTicket> CreateTicketAsync([NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); response.EnsureSuccessStatusCode(); var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); identity.AddOptionalClaim(ClaimTypes.NameIdentifier, FitbitAuthenticationHelper.GetIdentifier(payload), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.Name, FitbitAuthenticationHelper.GetLogin(payload), Options.ClaimsIssuer) .AddOptionalClaim("urn:fitbit:avatar", FitbitAuthenticationHelper.GetAvatar(payload), Options.ClaimsIssuer) .AddOptionalClaim("urn:fitbit:avatar150", FitbitAuthenticationHelper.GetAvatar150(payload), Options.ClaimsIssuer); var context = new OAuthCreatingTicketContext(Context, Options, Backchannel, tokens, payload) { Principal = new ClaimsPrincipal(identity), Properties = properties }; await Options.Events.CreatingTicket(context); if (context.Principal?.Identity == null) { return(null); } return(new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme)); }
/// <summary> /// Exchanges the authorization code for a authorization token from the remote provider. /// </summary> /// <param name="context">The <see cref="OAuthCodeExchangeContext"/>.</param> /// <returns>The response <see cref="OAuthTokenResponse"/>.</returns> protected virtual async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context) { var tokenRequestParameters = new Dictionary <string, string>() { { "client_id", Options.ClientId }, { "redirect_uri", context.RedirectUri }, { "client_secret", Options.ClientSecret }, { "code", context.Code }, { "grant_type", "authorization_code" }, }; // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier)) { tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier !); context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey); } var requestContent = new FormUrlEncodedContent(tokenRequestParameters !); var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint); requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); requestMessage.Content = requestContent; requestMessage.Version = Backchannel.DefaultRequestVersion; var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted); var body = await response.Content.ReadAsStringAsync(Context.RequestAborted); return(response.IsSuccessStatusCode switch { true => OAuthTokenResponse.Success(JsonDocument.Parse(body)), false => PrepareFailedOAuthTokenReponse(response, body) });
/// <summary> /// 通过Code获取Access Token(这是第二步) /// </summary> protected async Task <OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri, string appId) { var parameters = new Dictionary <string, string> { { "appid", appId }, { "secret", Options.Apps.First(p => p.AppId == appId).AppSecret }, { "code", code }, { "grant_type", "authorization_code" } }; _logger.LogDebug("code换取access_token"); var endpoint = QueryHelpers.AddQueryString(Options.TokenEndpoint, parameters); _logger.LogDebug(endpoint); var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted); if (response.IsSuccessStatusCode) { var result = await response.Content.ReadAsStringAsync(); _logger.LogDebug(result); var payload = JObject.Parse(result); if (payload.Properties().Any(p => p.Name == "errcode")) { return(OAuthTokenResponse.Failed(new Exception($"获取微信AccessToken出错。{result}"))); } return(OAuthTokenResponse.Success(payload)); } else { return(OAuthTokenResponse.Failed(new Exception("获取微信AccessToken出错。"))); } }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { string address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, "access_token", tokens.AccessToken !); using var request = new HttpRequestMessage(HttpMethod.Get, address); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted); throw new HttpRequestException("An error occurred while retrieving the user profile."); } using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); context.RunClaimActions(); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal !, context.Properties, Scheme.Name)); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context) { var tokenRequestParameters = new Dictionary <string, string> { ["grant_type"] = "authorization_code", ["redirect_uri"] = context.RedirectUri, ["code"] = context.Code, }; // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier)) { tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier !); context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey); } using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = CreateAuthorizationHeader(); request.Content = new FormUrlEncodedContent(tokenRequestParameters); using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); return(OAuthTokenResponse.Success(payload)); }
private async Task <(int ErrorCode, string?UserId)> GetUserIdentifierAsync(OAuthTokenResponse tokens) { // See https://open.work.weixin.qq.com/api/doc/90000/90135/91023 for details. var parameters = new Dictionary <string, string?> { ["access_token"] = tokens.AccessToken, ["code"] = Request.Query["code"], }; var address = QueryHelpers.AddQueryString(Options.UserIdentificationEndpoint, parameters); using var response = await Backchannel.GetAsync(address, Context.RequestAborted); if (!response.IsSuccessStatusCode) { await Log.UserIdentifierErrorAsync(Logger, response, Context.RequestAborted); throw new HttpRequestException("An error occurred while retrieving the user identifier."); } using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); var errorCode = payload.RootElement.TryGetProperty("errcode", out var errCodeElement) && errCodeElement.ValueKind == JsonValueKind.Number ? errCodeElement.GetInt32() : 0; return(errorCode, payload.RootElement.GetString("UserId")); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { using var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError("An error occurred while retrieving the user profile: the remote server " + "returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted)); throw new HttpRequestException("An error occurred while retrieving the user profile."); } using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); context.RunClaimActions(payload.RootElement.GetProperty("user")); await Options.Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal !, context.Properties, Scheme.Name)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync([NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError("An error occurred while retrieving the user profile: the remote server " + "returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync()); throw new HttpRequestException("An error occurred while retrieving the user profile."); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); identity.AddOptionalClaim(ClaimTypes.NameIdentifier, DropboxAuthenticationHelper.GetIdentifier(payload), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.Name, DropboxAuthenticationHelper.GetDisplayName(payload), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.Email, DropboxAuthenticationHelper.GetEmail(payload), Options.ClaimsIssuer); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme); var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload); await Options.Events.CreatingTicket(context); return(context.Ticket); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context) { // See https://open.work.weixin.qq.com/api/doc/90000/90135/91039 for details. var tokenRequestParameters = new Dictionary <string, string?>() { ["corpid"] = Options.ClientId, ["corpsecret"] = Options.ClientSecret, }; // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier)) { tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier !); context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey); } var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, tokenRequestParameters); using var response = await Backchannel.GetAsync(address, Context.RequestAborted); if (!response.IsSuccessStatusCode) { await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); return(OAuthTokenResponse.Success(payload)); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] string code, [NotNull] string redirectUri) { var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded")); request.Content = new FormUrlEncodedContent(new Dictionary <string, string> { ["redirect_uri"] = redirectUri, ["client_assertion"] = Options.ClientSecret, ["assertion"] = code, ["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer", ["client_assertion_type"] = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" }); var response = await Backchannel.SendAsync(request, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError("An error occurred while retrieving an access token: the remote server " + "returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync()); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); return(OAuthTokenResponse.Success(payload)); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context) { using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = CreateAuthorizationHeader(); var parameters = new Dictionary <string, string> { ["grant_type"] = "authorization_code", ["redirect_uri"] = context.RedirectUri, ["code"] = context.Code }; request.Content = new FormUrlEncodedContent(parameters !); using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError("An error occurred while retrieving an access token: the remote server " + "returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted)); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); return(OAuthTokenResponse.Success(payload)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { log.LogDebug("CreateTicketAsync called"); var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); var response = await Backchannel.SendAsync(request, Context.RequestAborted); response.EnsureSuccessStatusCode(); var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var context = new OAuthCreatingTicketContext(Context, Options, Backchannel, tokens, payload) { Properties = properties, Principal = new ClaimsPrincipal(identity) }; var identifier = MicrosoftAccountHelper.GetId(payload); if (!string.IsNullOrEmpty(identifier)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:microsoftaccount:id", identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } var name = MicrosoftAccountHelper.GetName(payload); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:microsoftaccount:name", name, ClaimValueTypes.String, Options.ClaimsIssuer)); } var email = MicrosoftAccountHelper.GetEmail(payload); if (!string.IsNullOrEmpty(email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer)); } await Options.Events.CreatingTicket(context); ISiteSettings site = siteResolver.Resolve(); if (site != null) { Claim siteGuidClaim = new Claim("SiteGuid", site.SiteGuid.ToString()); if (!identity.HasClaim(siteGuidClaim.Type, siteGuidClaim.Value)) { identity.AddClaim(siteGuidClaim); } } //return new AuthenticationTicket(notification.Principal, notification.Properties, notification.Options.AuthenticationScheme); return(new AuthenticationTicket(context.Principal, context.Properties, AuthenticationScheme.External)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync([NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string> { ["access_token"] = tokens.AccessToken, ["uid"] = tokens.Response.Value <string>("uid") }); HttpRequestMessage request = null; HttpResponseMessage response = null; try { request = new HttpRequestMessage(HttpMethod.Get, address); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError("An error occurred while retrieving the user profile: the remote server " + "returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync()); throw new HttpRequestException("An error occurred while retrieving the user profile."); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); // When the email address is not public, retrieve it from // the emails endpoint if the user:email scope is specified. if (!string.IsNullOrEmpty(Options.UserEmailsEndpoint) && !identity.HasClaim(claim => claim.Type == ClaimTypes.Email) && Options.Scope.Contains("user:email")) { var email = await GetEmailAsync(tokens); if (!string.IsNullOrEmpty(address)) { identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer)); } } var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload); context.RunClaimActions(payload); await Options.Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); } finally { request?.Dispose(); response?.Dispose(); } }
/// <inheritdoc /> protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { var uri = string.Format( CultureInfo.InvariantCulture, ShopifyAuthenticationDefaults.UserInformationEndpointFormat, properties.Items[ShopifyAuthenticationDefaults.ShopNameAuthenticationProperty]); using var request = new HttpRequestMessage(HttpMethod.Get, uri); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Add("X-Shopify-Access-Token", tokens.AccessToken); using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted); throw new HttpRequestException("An error occurred while retrieving the shop profile."); } using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); // In Shopify, the customer can modify the scope given to the app. Apps should verify // that the customer is allowing the required scope. var actualScope = tokens.Response !.RootElement.GetString("scope") ?? string.Empty; var isPersistent = true; // If the request was for a "per-user" (i.e. no offline access) if (tokens.Response.RootElement.TryGetProperty("expires_in", out var expiresInProperty)) { isPersistent = false; if (expiresInProperty.TryGetInt32(out var expiresIn)) { var expires = Clock.UtcNow.AddSeconds(expiresIn); identity.AddClaim(new Claim(ClaimTypes.Expiration, expires.ToString("O", CultureInfo.InvariantCulture), ClaimValueTypes.DateTime)); } actualScope = tokens.Response.RootElement.GetString("associated_user_scope") ?? string.Empty; var userData = tokens.Response.RootElement.GetString("associated_user") ?? string.Empty; identity.AddClaim(new Claim(ClaimTypes.UserData, userData)); } identity.AddClaim(new Claim(ClaimTypes.IsPersistent, isPersistent.ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Boolean)); identity.AddClaim(new Claim(ShopifyAuthenticationDefaults.ShopifyScopeClaimType, actualScope)); var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); context.RunClaimActions(); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal !, context.Properties, Scheme.Name)); }
/// <summary> /// 与本站通信,可获取用户基本信息 /// </summary> protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var openIdEndpoint = Options.OpenIdEndpoint + "?access_token=" + tokens.AccessToken; var response = await Backchannel.GetAsync(openIdEndpoint, Context.RequestAborted); response.EnsureSuccessStatusCode(); // 要不要这么懒……这回用正则看看 var tmp = await response.Content.ReadAsStringAsync(); var regex = new System.Text.RegularExpressions.Regex("callback\\((?<json>[ -~]+)\\);"); // just throw it when error appears. var json = JObject.Parse(regex.Match(tmp).Groups["json"].Value); var identifier = TencentHelper.GetId(json); if (!string.IsNullOrEmpty(identifier)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:qq:id", identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } var content = new FormUrlEncodedContent(new Dictionary <string, string> { { "oauth_consumer_key", Options.ClientId }, { "access_token", tokens.AccessToken }, { "openid", identifier } }); response = await Backchannel.PostAsync(Options.UserInformationEndpoint, content); response.EnsureSuccessStatusCode(); var info = JObject.Parse(await response.Content.ReadAsStringAsync()); info.Add("id", identifier); var notification = new OAuthCreatingTicketContext(Context, Options, Backchannel, tokens, info) { Properties = properties, Principal = new ClaimsPrincipal(identity) }; var name = TencentHelper.GetName(info); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:qq:name", name, ClaimValueTypes.String, Options.ClaimsIssuer)); } var figure = TencentHelper.GetFigure(info); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim("urn:qq:figure", figure, ClaimValueTypes.String, Options.ClaimsIssuer)); } await Options.Events.CreatingTicket(notification); return(new AuthenticationTicket(notification.Principal, notification.Properties, notification.Options.AuthenticationScheme)); }
protected override async Task <OpenIdConnectMessage> RedeemAuthorizationCodeAsync(OpenIdConnectMessage tokenEndpointRequest) { //Logger.RedeemingCodeForTokens(); OpenIdConnectHandler idConnectHandler = this; OpenIdConnectConfiguration configurationAsync = await idConnectHandler.Options.ConfigurationManager.GetConfigurationAsync(CancellationToken.None); var requestMessage = new HttpRequestMessage(HttpMethod.Post, configurationAsync.TokenEndpoint); //add header ipv body var basicAuthHeader = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{Options.ClientId}:{Options.ClientSecret}")); requestMessage.Headers.Add("Authorization", basicAuthHeader); var parameters = tokenEndpointRequest.Parameters; parameters.Remove("client_id"); parameters.Remove("client_secret"); requestMessage.Content = new FormUrlEncodedContent(parameters); var responseMessage = await Backchannel.SendAsync(requestMessage); var contentMediaType = responseMessage.Content.Headers.ContentType?.MediaType; if (string.IsNullOrEmpty(contentMediaType)) { Logger.LogDebug($"Unexpected token response format. Status Code: {(int)responseMessage.StatusCode}. Content-Type header is missing."); } else if (!string.Equals(contentMediaType, "application/json", StringComparison.OrdinalIgnoreCase)) { Logger.LogDebug($"Unexpected token response format. Status Code: {(int)responseMessage.StatusCode}. Content-Type {responseMessage.Content.Headers.ContentType}."); } // Error handling: // 1. If the response body can't be parsed as json, throws. // 2. If the response's status code is not in 2XX range, throw OpenIdConnectProtocolException. If the body is correct parsed, // pass the error information from body to the exception. OpenIdConnectMessage message; try { var responseContent = await responseMessage.Content.ReadAsStringAsync(); message = new OpenIdConnectMessage(responseContent); } catch (Exception ex) { throw new OpenIdConnectProtocolException($"Failed to parse token response body as JSON. Status Code: {(int)responseMessage.StatusCode}. Content-Type: {responseMessage.Content.Headers.ContentType}", ex); } if (!responseMessage.IsSuccessStatusCode) { //throw CreateOpenIdConnectProtocolException(message, responseMessage); } return(message); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { // See https://opendocs.alipay.com/apis/api_2/alipay.user.info.share for details. var parameters = new SortedDictionary <string, string?>() { ["app_id"] = Options.ClientId, ["auth_token"] = tokens.AccessToken, ["charset"] = "utf-8", ["format"] = "JSON", ["method"] = "alipay.user.info.share", ["sign_type"] = "RSA2", ["timestamp"] = Clock.UtcNow.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), ["version"] = "1.0", }; parameters.Add("sign", GetRSA2Signature(parameters)); var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, parameters); using var response = await Backchannel.GetAsync(address, Context.RequestAborted); if (!response.IsSuccessStatusCode) { await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted); throw new HttpRequestException("An error occurred while retrieving user information."); } using var stream = await response.Content.ReadAsStreamAsync(Context.RequestAborted); using var document = JsonDocument.Parse(stream); var rootElement = document.RootElement; if (!rootElement.TryGetProperty("alipay_user_info_share_response", out JsonElement mainElement)) { var errorCode = rootElement.GetProperty("error_response").GetProperty("code").GetString() !; throw new Exception($"An error (Code:{errorCode}) occurred while retrieving user information."); } if (!ValidateReturnCode(mainElement, out var code)) { throw new Exception($"An error (Code:{code}) occurred while retrieving user information."); } identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, mainElement.GetString("user_id") !, ClaimValueTypes.String, Options.ClaimsIssuer)); var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, mainElement); context.RunClaimActions(); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal !, context.Properties, Scheme.Name)); }
private async Task<bool> TryRefreshTokenAsync(AuthenticationTicket ticket) { // Refresh var rfrshToken = ticket.Properties.GetTokenValue("refresh_token"); var tokenRequestParameters = new Dictionary<string, string>() { { "client_id", Options.ClientId }, { "client_secret", Options.ClientSecret }, { "grant_type", "refresh_token" }, { "refresh_token", rfrshToken }, { "scope", "identify guilds" } }; var requestContent = new FormUrlEncodedContent(tokenRequestParameters); using var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint); requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); requestMessage.Content = requestContent; var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted); if (response.IsSuccessStatusCode) { await using var stream = await response.Content.ReadAsStreamAsync(); var payload = await JsonDocument.ParseAsync(stream); var tokens = OAuthTokenResponse.Success(payload); ticket.Properties.UpdateTokenValue("access_token", tokens.AccessToken); ticket.Properties.UpdateTokenValue("refresh_token", tokens.RefreshToken); if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out var value)) { var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value); ticket.Properties.UpdateTokenValue("expires_at", expiresAt.ToString("o", CultureInfo.InvariantCulture)); } if (ticket.Principal.Identity is ClaimsIdentity identity) { var existingClaim = identity.FindFirst("discord"); if (existingClaim != null && identity.TryRemoveClaim(existingClaim)) { identity.AddClaim(new Claim("discord", tokens.AccessToken)); } } if (ticket.Properties.ExpiresUtc.HasValue && ticket.Properties.IssuedUtc.HasValue) { var delta = ticket.Properties.ExpiresUtc - ticket.Properties.IssuedUtc; ticket.Properties.IssuedUtc = Clock.UtcNow; ticket.Properties.ExpiresUtc = Clock.UtcNow + delta; } return true; } return false; }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { var identifier = await GetUserIdentifierAsync(tokens); if (string.IsNullOrEmpty(identifier)) { throw new HttpRequestException("An error occurred while retrieving the user identifier."); } identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string> { ["oauth_consumer_key"] = Options.ClientId, ["access_token"] = tokens.AccessToken, ["openid"] = identifier, }); var response = await Backchannel.GetAsync(address); if (!response.IsSuccessStatusCode) { Logger.LogError("An error occurred while retrieving the user profile: the remote server " + "returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync()); throw new HttpRequestException("An error occurred while retrieving user information."); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var status = payload.Value <int>("ret"); if (status != 0) { Logger.LogError("An error occurred while retrieving the user profile: the remote server " + "returned a {Status} response with the following message: {Message}.", /* Status: */ status, /* Message: */ payload.Value <string>("msg")); throw new HttpRequestException("An error occurred while retrieving user information."); } var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload); context.RunClaimActions(payload); await Options.Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { if (identity == null) { throw new ArgumentNullException(nameof(identity)); } if (tokens == null) { throw new ArgumentNullException(nameof(tokens)); } OAuthCreatingTicketContext context = null; if (Options.Scope.First() == WeChatScopes.snsapi_userinfo) { var url = Options.UserInformationEndpoint + $"?access_token={UrlEncoder.Default.Encode(tokens.AccessToken)}" + $"&openid={UrlEncoder.Default.Encode(tokens.Response.RootElement.GetString("openid"))}" + $"&lang=" + Options.Language; var request = new HttpRequestMessage(HttpMethod.Get, url); var response = await Backchannel.SendAsync(request, Context.RequestAborted); var content = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { var payload = JsonDocument.Parse(content); context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); context.RunClaimActions(payload.RootElement); } else { var weChatException = new WeChatException("获取微信用户信息失败:HttpClient返回错误代码," + $"Status:{response.StatusCode},Headers:{response.Headers.ToString()},Body:{content}"); Logger.LogDebug(weChatException, "WeChatHandler CreateTicketAsync"); throw weChatException; } } if (context == null) { context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, tokens.Response.RootElement); context.RunClaimActions(tokens.Response.RootElement); } await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { using var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError("An error occurred while retrieving the user profile: the remote server " + "returned a {Status} response with the following payload: {Headers} {Body}.", response.StatusCode, response.Headers.ToString(), await response.Content.ReadAsStringAsync()); throw new HttpRequestException("An error occurred while retrieving the user profile."); } using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); context.RunClaimActions(); await Options.Events.CreatingTicket(context); // store token and user in database string id = ""; string emailAddress = ""; string name = ""; foreach (Claim claim in identity.Claims) { switch (claim.Type) { case "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": id = claim.Value; break; case "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": emailAddress = claim.Value; break; case "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": name = claim.Value; break; } } CommentLinkUser commentLinkUser = new CommentLinkUser(id, emailAddress, name, tokens); _ = CosmosDb.UpsertItem(commentLinkUser); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
/// <summary> /// 获取用户参数,与本机通信 /// </summary> protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var openId = XiaoMiHelper.GetOpenId(tokens.Response); if (!string.IsNullOrEmpty(openId)) { identity.AddClaim(new Claim("urn:mi:openid", openId, ClaimValueTypes.String, Options.ClaimsIssuer)); } var type = tokens.TokenType.ToEnum <TokenType>(); var content = await new FormUrlEncodedContent(new Dictionary <string, string> { { "clientId", Options.ClientId }, { "token", tokens.AccessToken } }).ReadAsStringAsync(); var message = new HttpRequestMessage(HttpMethod.Get, $"{Options.UserInformationEndpoint}?{content}"); if (type == TokenType.MAC) { var key = tokens.Response.Value <string>("mac_key"); var algorithm = tokens.Response.Value <string>("mac_algorithm"); message.Headers.Authorization = new AuthenticationHeaderValue("MAC", ComputeMAC(tokens.AccessToken, key, message, algorithm)); } var response = await Backchannel.SendAsync(message, Context.RequestAborted); response.EnsureSuccessStatusCode(); var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme); var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload); var identifier = XiaoMiHelper.GetId(payload); if (!string.IsNullOrEmpty(identifier)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:mi:id", identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } var name = XiaoMiHelper.GetName(payload); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:mi:name", name, ClaimValueTypes.String, Options.ClaimsIssuer)); } var icon = XiaoMiHelper.GetIcon(payload); if (!string.IsNullOrEmpty(icon)) { identity.AddClaim(new Claim("urn:mi:icon", icon, ClaimValueTypes.String, Options.ClaimsIssuer)); } await Options.Events.CreatingTicket(context); return(context.Ticket); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { (var errorCode, var openId, var unionId) = await GetUserIdentifierAsync(tokens); if (errorCode != 0 || string.IsNullOrEmpty(openId)) { throw new HttpRequestException($"An error (Code:{errorCode}) occurred while retrieving the user identifier."); } identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, openId, ClaimValueTypes.String, Options.ClaimsIssuer)); if (!string.IsNullOrEmpty(unionId)) { identity.AddClaim(new Claim(QQAuthenticationConstants.Claims.UnionId, unionId, ClaimValueTypes.String, Options.ClaimsIssuer)); } var parameters = new Dictionary <string, string?>(3) { ["oauth_consumer_key"] = Options.ClientId, ["access_token"] = tokens.AccessToken, ["openid"] = openId, }; var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, parameters); using var response = await Backchannel.GetAsync(address); if (!response.IsSuccessStatusCode) { await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted); throw new HttpRequestException("An error occurred while retrieving user information."); } using var stream = await response.Content.ReadAsStreamAsync(Context.RequestAborted); using var payload = JsonDocument.Parse(stream); var status = payload.RootElement.GetProperty("ret").GetInt32(); if (status != 0) { Log.UserProfileErrorCode(Logger, status, payload.RootElement.GetString("msg")); throw new HttpRequestException("An error occurred while retrieving user information."); } var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); context.RunClaimActions(); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal !, context.Properties, Scheme.Name)); }
/// <summary> /// Step2:通过Authorization Code获取Access Token /// http://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token /// </summary> protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context) { var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string>() { ["client_id"] = Options.ClientId, ["client_secret"] = Options.ClientSecret, ["code"] = context.Code, ["grant_type"] = "authorization_code", ["redirect_uri"] = context.RedirectUri, }); var response = await Backchannel.GetAsync(address); if (!response.IsSuccessStatusCode) { Logger.LogError("An error occurred while retrieving an access token: the remote server returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync()); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } // 成功: access_token=FE04************************CCE2&expires_in=7776000&refresh_token=88E4************************BE14 // 失败: callback( {"error":123456 ,"error_description":"**************"} ); var responseString = await response.Content.ReadAsStringAsync(); if (responseString.StartsWith("callback")) { Logger.LogError("An error occurred while retrieving an access token: the remote server " + "returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync()); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } JsonDocument payload = JsonDocument.Parse("{}"); var responseParams = responseString.Split('&'); var buffer = new ArrayBufferWriter <byte>(); var write = new Utf8JsonWriter(buffer); foreach (var parm in responseParams) { var kv = parm.Split('='); write.WritePropertyName(kv[0]); write.WriteStringValue(kv[1]); } return(OAuthTokenResponse.Success(payload)); }