protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { // 首先获取OpenId var openIdEndpoint = QueryHelpers.AddQueryString(Options.OpenIdEndpoint, "access_token", tokens.AccessToken); var openIdResponse = await Backchannel.GetAsync(openIdEndpoint, Context.RequestAborted); var openIdContent = await openIdResponse.Content.ReadAsStringAsync(); openIdContent = openIdContent.TrimStart("callback( ").TrimEnd(" );\n"); var openIdPayload = JObject.Parse(openIdContent); // 存储openid,绑定到系统的用户,作为系统在第三方的唯一标识 var openId = openIdPayload["openid"].Value <string>(); var tokenRequestParameters = new Dictionary <string, string>() { { "access_token", tokens.AccessToken }, { "oauth_consumer_key", Options.ClientId }, { "openid", openId }, }; var endpoint = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, tokenRequestParameters); var requestMessage = new HttpRequestMessage(HttpMethod.Get, endpoint); requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted); //var endpoint = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, // "access_token", tokens.AccessToken); //var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"An error occurred when retrieving Facebook user information ({response.StatusCode}). Please check if the authentication information is correct and the corresponding Facebook Graph API is enabled."); } var jObj = JObject.Parse(await response.Content.ReadAsStringAsync()); // 填充openid jObj["openid"] = openId; using (var payload = JsonDocument.Parse(jObj.ToString()))// { 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, properties, Scheme.Name)); } }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { (int errorCode, string?userId) = await GetUserIdentifierAsync(tokens); if (errorCode != 0 || string.IsNullOrEmpty(userId)) { throw new Exception($"An error (Code:{errorCode}) occurred while retrieving the user identifier."); } // See https://open.work.weixin.qq.com/api/doc/90000/90135/90196 for details. string address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string?> { ["access_token"] = tokens.AccessToken, ["userid"] = userId, }); using var response = await Backchannel.GetAsync(address, 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 user information."); } using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); errorCode = payload.RootElement.GetProperty("errcode").GetInt32(); if (errorCode != 0) { Logger.LogError("An error occurred while retrieving the user profile: the remote server " + "returned a {ErrorCode} response with the following message: {Message} .", /* ErrorCode: */ errorCode, /* Message: */ payload.RootElement.GetString("errmsg")); throw new Exception("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 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) { 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>[ -~]+)\\);"); var json = JObject.Parse(regex.Match(tmp).Groups["json"].Value); var identifier = QQHelper.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 ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme); var notification = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, info); var name = QQHelper.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 = QQHelper.GetFigure(info); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim("urn:qq:figure", figure, ClaimValueTypes.String, Options.ClaimsIssuer)); } await Options.Events.CreatingTicket(notification); return(notification.Ticket); }
/// <summary> /// Last step: /// create ticket from remote server /// </summary> /// <param name="identity"></param> /// <param name="properties"></param> /// <param name="tokens"></param> /// <returns></returns> protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string> { ["access_token"] = tokens.AccessToken, ["openid"] = tokens.Response.Value <string>("openid") }); 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()); if (!string.IsNullOrEmpty(payload.Value <string>("errcode"))) { 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."); } identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, WeixinAuthenticationHelper.GetUnionid(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim(ClaimTypes.Name, WeixinAuthenticationHelper.GetNickname(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim(ClaimTypes.Gender, WeixinAuthenticationHelper.GetSex(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim(ClaimTypes.Country, WeixinAuthenticationHelper.GetCountry(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:weixin:openid", WeixinAuthenticationHelper.GetOpenId(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:weixin:province", WeixinAuthenticationHelper.GetProvince(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:weixin:city", WeixinAuthenticationHelper.GetCity(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:weixin:headimgurl", WeixinAuthenticationHelper.GetHeadimgUrl(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:weixin:privilege", WeixinAuthenticationHelper.GetPrivilege(payload), Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:weixin:user_info", payload.ToString(), Options.ClaimsIssuer)); 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)); }
protected override async Task <AuthenticationTicket> GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) { string graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(tokens.AccessToken); if (Options.SendAppSecretProof) { graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(tokens.AccessToken); } var graphResponse = await Backchannel.GetAsync(graphAddress, Context.RequestAborted); graphResponse.EnsureSuccessStatusCode(); string text = await graphResponse.Content.ReadAsStringAsync(); JObject user = JObject.Parse(text); var context = new FacebookAuthenticatedContext(Context, Options, user, tokens); context.Identity = new ClaimsIdentity( Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.UserName)) { context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, ClaimValueTypes.String, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Email)) { context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Name)) { context.Identity.AddClaim(new Claim("urn:facebook:name", context.Name, ClaimValueTypes.String, Options.AuthenticationType)); // Many Facebook accounts do not set the UserName field. Fall back to the Name field instead. if (string.IsNullOrEmpty(context.UserName)) { context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, ClaimValueTypes.String, Options.AuthenticationType)); } } if (!string.IsNullOrEmpty(context.Link)) { context.Identity.AddClaim(new Claim("urn:facebook:link", context.Link, ClaimValueTypes.String, Options.AuthenticationType)); } context.Properties = properties; await Options.Notifications.Authenticated(context); return(new AuthenticationTicket(context.Identity, context.Properties)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( ClaimsIdentity identity, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, OAuthTokenResponse tokens) { var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, "access_token", tokens.AccessToken); Dictionary <string, string> queryString = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase) { ["application_key"] = Options.PublicKey, ["format"] = "json", ["__online"] = "false" }; if (Options.Fields.Count != 0) { queryString.Add("fields", string.Join(",", Options.Fields)); } queryString.Add("sig", GetSignature(tokens.AccessToken, queryString)); address = QueryHelpers.AddQueryString(address, queryString); var response = await Backchannel.GetAsync(address, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError("Произошла ошибка при получении профиля пользователя: удаленный сервер " + "вернул {Status} ответ со следующей информацией: {Headers} {Body}.", response.StatusCode, response.Headers.ToString(), await response.Content.ReadAsStringAsync()); throw new HttpRequestException("Произошла ошибка при получении профиля пользователя."); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var user = (JObject)payload; //identity.AddOptionalClaim(ClaimTypes.NameIdentifier, user.Value<string>("uid"), Options.ClaimsIssuer) // .AddOptionalClaim(ClaimTypes.Name, user.Value<string>("name"), Options.ClaimsIssuer) // .AddOptionalClaim(ClaimTypes.GivenName, user.Value<string>("first_name"), Options.ClaimsIssuer) // .AddOptionalClaim(ClaimTypes.Surname, user.Value<string>("last_name"), Options.ClaimsIssuer) // .AddOptionalClaim(ClaimTypes.Email, user.Value<string>("email"), Options.ClaimsIssuer); var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, user); context.RunClaimActions(); 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) { var facebookHandler = this; 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>[ -~]+)\\);"); var json = JObject.Parse(regex.Match(tmp).Groups["json"].Value); var identifier = json.Value <string>("openid"); 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 name = info.Value <string>("nickname"); 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 = info.Value <string>("figureurl_qq_1"); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim("urn:qq:figure", figure, ClaimValueTypes.String, Options.ClaimsIssuer)); } //JObject user = JObject.Parse(await async.Content.ReadAsStringAsync()); OAuthCreatingTicketContext context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, facebookHandler.Context, facebookHandler.Scheme, facebookHandler.Options, facebookHandler.Backchannel, tokens); context.RunClaimActions(); await facebookHandler.Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, facebookHandler.Scheme.Name)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { //获取OpenId string openIdEndpoint = QueryHelpers.AddQueryString(Options.OpenIdEndpoint, "access_token", tokens.AccessToken); HttpResponseMessage openIdResponse = await Backchannel.GetAsync(openIdEndpoint, Context.RequestAborted); if (!openIdResponse.IsSuccessStatusCode) { throw new HttpRequestException($"未能检索QQ Connect的OpenId(返回状态码:{openIdResponse.StatusCode}),请检查access_token是正确。"); } JObject json = JObject.Parse(企鹅的返回不拘一格传入这里统一转换为JSON(await openIdResponse.Content.ReadAsStringAsync())); string openId = GetOpenId(json); //获取用户信息 Dictionary <string, string> parameters = new Dictionary <string, string> { { "openid", openId }, { "access_token", tokens.AccessToken }, { "oauth_consumer_key", Options.ClientId } }; string userInformationEndpoint = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, parameters); HttpResponseMessage userInformationResponse = await Backchannel.GetAsync(userInformationEndpoint, Context.RequestAborted); if (!userInformationResponse.IsSuccessStatusCode) { throw new HttpRequestException($"未能检索QQ Connect的用户信息(返回状态码:{userInformationResponse.StatusCode}),请检查参数是否正确。"); } #if NETSTANDARD JObject payload = JObject.Parse(await userInformationResponse.Content.ReadAsStringAsync()); //identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, openId, ClaimValueTypes.String, Options.ClaimsIssuer)); payload.Add("openid", openId); OAuthCreatingTicketContext 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)); #else string json2 = await userInformationResponse.Content.ReadAsStringAsync(); JObject payload = JObject.Parse(json2); JsonDocument document = JsonDocument.Parse(json2); //identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, openId, ClaimValueTypes.String, Options.ClaimsIssuer)); payload.Add("openid", openId); OAuthCreatingTicketContext context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, document.RootElement); context.RunClaimActions(); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); #endif }
/// <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(string code, string redirectUri) { var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string>() { ["client_id"] = Options.ClientId, ["client_secret"] = Options.ClientSecret, ["code"] = code, ["grant_type"] = "authorization_code", ["redirect_uri"] = 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."))); } JObject payload = new JObject(); var responseParams = responseString.Split('&'); foreach (var parm in responseParams) { var kv = parm.Split('='); payload[kv[0]] = kv[1]; } return(OAuthTokenResponse.Success(payload)); }
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, ["v"] = !string.IsNullOrEmpty(Options.ApiVersion) ? Options.ApiVersion : VkontakteAuthenticationDefaults.ApiVersion }); if (Options.Fields.Count != 0) { address = QueryHelpers.AddQueryString(address, "fields", string.Join(",", Options.Fields)); } HttpResponseMessage response = null; try { response = await Backchannel.GetAsync(address, 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 container = JObject.Parse(await response.Content.ReadAsStringAsync()); var payload = container["response"].First as JObject; if (tokens.Response["email"] != null) { payload.Add("email", tokens.Response["email"]); } 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 { response?.Dispose(); } }
protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync() { IQueryCollection query = Request.Query; var state = query["state"]; var properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(HandleRequestResult.Fail("The oauth state was missing or invalid.")); } string ticket = query["ticket"].FirstOrDefault(); string returnUrl = query["returnUrl"].FirstOrDefault(); if (ticket == null) { return(HandleRequestResult.Fail("Ticket should never be null.")); } string serviceUri = CurrentUri; string userInformationUrl = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string> { ["ticket"] = ticket, ["service"] = GetService(CurrentUri) }); HttpResponseMessage response = await Backchannel.GetAsync(userInformationUrl); var xdoc = XDocument.Load(await response.Content.ReadAsStreamAsync()); string xmlErrorMessage = GetXmlErrorMessage(xdoc); if (xmlErrorMessage != null) { return(HandleRequestResult.Fail(xmlErrorMessage)); } IEnumerable <Claim> claims = GetXmlClaims(xdoc); var identity = new ClaimsIdentity(claims, ClaimsIssuer); var token = OAuthTokenResponse.Failed(new Exception("Token not available.")); AuthenticationTicket authenticationTicket = await CreateTicketAsync(identity, properties, token); if (authenticationTicket != null) { return(HandleRequestResult.Success(authenticationTicket)); } else { return(HandleRequestResult.Fail("Failed to retrieve user information from remote user.", properties)); } }
/// <summary> Creates ticket asynchronous. </summary> /// <exception cref="HttpRequestException"> Thrown when a HTTP Request error condition occurs. </exception> /// <param name="identity"> The identity. </param> /// <param name="properties"> The properties. </param> /// <param name="tokens"> The tokens. </param> /// <returns> The new ticket asynchronous. </returns> protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { // construct endpoint-address var endpoint = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, "access_token", tokens.AccessToken); // query endpoint var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted); if (!response.IsSuccessStatusCode) { throw new HttpRequestException( $"An error occurred when retrieving Facebook user information ({response.StatusCode}). Please check if the authentication information is correct and the corresponding Facebook Graph API is enabled."); } // parse endpoint-response var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var user = JsonConvert.DeserializeObject <AmazonUser>(await response.Content.ReadAsStringAsync()); // parse Amazon-content manually var identifier = user.UserId; if (!string.IsNullOrEmpty(identifier)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } var name = user.Name; if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); } var email = user.EMail; if (!string.IsNullOrEmpty(email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer)); } 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)); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context) { // See https://opendocs.alipay.com/apis/api_9/alipay.system.oauth.token for details. var tokenRequestParameters = new SortedDictionary <string, string?>() { ["app_id"] = Options.ClientId, ["charset"] = "utf-8", ["code"] = context.Code, ["format"] = "JSON", ["grant_type"] = "authorization_code", ["method"] = "alipay.system.oauth.token", ["sign_type"] = "RSA2", ["timestamp"] = Clock.UtcNow.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), ["version"] = "1.0", }; tokenRequestParameters.Add("sign", GetRSA2Signature(tokenRequestParameters)); // 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, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { await Log.AccessTokenError(Logger, response, Context.RequestAborted); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } using var stream = await response.Content.ReadAsStreamAsync(Context.RequestAborted); using var document = JsonDocument.Parse(stream); var mainElement = document.RootElement.GetProperty("alipay_system_oauth_token_response"); if (!ValidateReturnCode(mainElement, out var code)) { return(OAuthTokenResponse.Failed(new Exception($"An error (Code:{code}) occurred while retrieving an access token."))); } var payload = JsonDocument.Parse(mainElement.GetRawText()); return(OAuthTokenResponse.Success(payload)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( ClaimsIdentity identity, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, OAuthTokenResponse tokens) { var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, "access_token", tokens.AccessToken); if (Options.Fields.Count != 0) { address = QueryHelpers.AddQueryString(address, "fields", string.Join(",", Options.Fields)); } var response = await Backchannel.GetAsync(address, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError("Произошла ошибка при получении профиля пользователя: удаленный сервер " + "вернул {Status} ответ со следующей информацией: {Headers} {Body}.", response.StatusCode, response.Headers.ToString(), await response.Content.ReadAsStringAsync()); throw new HttpRequestException("Произошла ошибка при получении профиля пользователя."); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var user = (JObject)payload["response"][0]; foreach (var scope in Options.Scope) { var scope_value = tokens.Response.Value <string>(scope); if (!string.IsNullOrEmpty(scope_value)) { user.Add(scope, scope_value); } } identity.AddOptionalClaim(ClaimTypes.NameIdentifier, user.Value <string>("uid"), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.GivenName, user.Value <string>("first_name"), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.Surname, user.Value <string>("last_name"), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.Email, user.Value <string>("email"), Options.ClaimsIssuer); var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, user); context.RunClaimActions(); 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 address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string> { ["access_token"] = tokens.AccessToken, ["openid"] = tokens.Response.Value <string>("openid") }); HttpResponseMessage response = null; try { 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()); if (!string.IsNullOrEmpty(payload.Value <string>("errcode"))) { 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 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 { response?.Dispose(); } }
/// <summary> /// 微信登录 /// </summary> /// <returns></returns> private string GetAccessToken() { var parameters = new Dictionary <string, string> { { "corpid", Options.AppId }, { "corpsecret", Options.AppKey } }; var loginurl = QueryHelpers.AddQueryString("https://qyapi.weixin.qq.com/cgi-bin/gettoken", parameters); var result = Backchannel.GetAsync(loginurl).Result.Content.ReadAsStringAsync().Result; var res = Newtonsoft.Json.JsonConvert.DeserializeObject <WeChatCompanyAccessTokenResult>(result); return(res.access_token); }
/// <summary> ///2.1子步骤>>向认证服务器申请令牌 /// </summary> protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context) { var tokenRequestParameters = new Dictionary <string, string> { { "appid", Options.ClientId }, { "appsecret", Options.ClientSecret } }; var userInfoEndpoint = QueryHelpers.AddQueryString(Options.TokenEndpoint, tokenRequestParameters); var response = await Backchannel.GetAsync(userInfoEndpoint, Context.RequestAborted); return(response.IsSuccessStatusCode ? OAuthTokenResponse.Success(JsonDocument.Parse(await response.Content.ReadAsStringAsync())) : OAuthTokenResponse.Failed(new Exception("OAuth token failure"))); }
/// <summary> /// 获取 相关令牌 /// </summary> /// <param name="code">授权码</param> /// <param name="redirectUri">回调地址</param> protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri) { var query = new QueryBuilder { { "appid", Options.AppId }, { "secret", Options.AppSecret }, { "code", code }, { "grant_type", "authorization_code" }, { "redirect_uri", redirectUri } }; var response = await Backchannel.GetAsync(Options.TokenEndpoint + query, Context.RequestAborted); response.EnsureSuccessStatusCode(); return(new OAuthTokenResponse(JObject.Parse(await response.Content.ReadAsStringAsync()))); }
protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string> { ["access_token"] = tokens.AccessToken, ["openid"] = tokens.Response.GetRootString("openid") }); 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 = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); if (!string.IsNullOrEmpty(payload.GetRootString("errcode"))) { 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 context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); context.RunClaimActions(); await Events.CreatingTicket(context); // TODO: 此处通过唯一的 CorrelationId, 将 properties生成的State缓存删除 var state = Request.Query["state"]; var stateCacheKey = WeChatOfficialStateCacheItem.CalculateCacheKey(state.ToString().ToMd5(), null); await Cache.RemoveAsync(stateCacheKey, token : Context.RequestAborted); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context) { // See https://opendocs.alipay.com/apis/api_9/alipay.system.oauth.token for details. var sortedParams = new SortedDictionary <string, string>() { ["app_id"] = Options.ClientId, ["charset"] = "utf-8", ["code"] = context.Code, ["format"] = "JSON", ["grant_type"] = "authorization_code", ["method"] = "alipay.system.oauth.token", ["sign_type"] = "RSA2", ["timestamp"] = Clock.UtcNow.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), ["version"] = "1.0", }; sortedParams.Add("sign", GetRSA2Signature(sortedParams)); string address = QueryHelpers.AddQueryString(Options.TokenEndpoint, sortedParams !); using var response = await Backchannel.GetAsync(address, 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."))); } using var stream = await response.Content.ReadAsStreamAsync(Context.RequestAborted); using var document = JsonDocument.Parse(stream); var mainElement = document.RootElement.GetProperty("alipay_system_oauth_token_response"); if (!ValidateReturnCode(mainElement, out string code)) { return(OAuthTokenResponse.Failed(new Exception($"An error (Code:{code}) occurred while retrieving an access token."))); } var payload = JsonDocument.Parse(mainElement.GetRawText()); return(OAuthTokenResponse.Success(payload)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { var parameters = new Dictionary <string, string?> { ["access_token"] = tokens.AccessToken, ["openid"] = tokens.Response?.RootElement.GetString("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."); } var json = await response.Content.ReadAsStringAsync(Context.RequestAborted); using var payload = JsonDocument.Parse(json); var errorCode = payload.RootElement.GetString("errcode"); if (!string.IsNullOrEmpty(errorCode)) { Log.UserProfileErrorCode(Logger, errorCode, response.Headers.ToString(), json); throw new HttpRequestException("An error occurred while retrieving user information."); } (var openId, var unionId) = GetUserIdentifier(payload.RootElement); var nameIdentifier = !string.IsNullOrWhiteSpace(unionId) ? unionId : openId; identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, nameIdentifier !, ClaimValueTypes.String, Options.ClaimsIssuer)); 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 <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { (var errorCode, var userId) = await GetUserIdentifierAsync(tokens); if (errorCode != 0 || string.IsNullOrEmpty(userId)) { throw new Exception($"An error (Code:{errorCode}) occurred while retrieving the user identifier."); } // See https://open.work.weixin.qq.com/api/doc/90000/90135/90196 for details. var parameters = new Dictionary <string, string?> { ["access_token"] = tokens.AccessToken, ["userid"] = userId, }; 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 payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); errorCode = payload.RootElement.GetProperty("errcode").GetInt32(); if (errorCode != 0) { Log.UserProfileErrorCode(Logger, errorCode, payload.RootElement.GetString("errmsg")); throw new Exception("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)); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri) { log.LogDebug("ExchangeCodeAsync called with code " + code + " redirectUri " + redirectUri); //var queryBuilder = new QueryBuilder() //{ // { "grant_type", "authorization_code" }, // { "code", code }, // { "redirect_uri", redirectUri }, // { "client_id", Options.AppId }, // { "client_secret", Options.AppSecret }, //}; var currentSite = await GetSite(); var tenantFbOptions = new MultiTenantFacebookOptionsResolver( Options, currentSite, multiTenantOptions); var queryBuilder = new QueryBuilder() { { "grant_type", "authorization_code" }, { "code", code }, { "redirect_uri", tenantFbOptions.ResolveRedirectUrl(redirectUri) }, { "client_id", tenantFbOptions.AppId }, { "client_secret", tenantFbOptions.AppSecret }, }; var response = await Backchannel.GetAsync(Options.TokenEndpoint + queryBuilder.ToString(), Context.RequestAborted); response.EnsureSuccessStatusCode(); var form = new FormCollection(FormReader.ReadForm(await response.Content.ReadAsStringAsync())); var payload = new JObject(); foreach (string key in form.Keys) { //payload.Add(string.Equals(key, "expires", StringComparison.OrdinalIgnoreCase) ? "expires_in" : key, form[key]); payload.Add(string.Equals(key, "expires", StringComparison.OrdinalIgnoreCase) ? "expires_in" : key, (string)form[key]); } // The refresh token is not available. return(new OAuthTokenResponse(payload)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { string address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string?> { ["access_token"] = tokens.AccessToken, ["v"] = !string.IsNullOrEmpty(Options.ApiVersion) ? Options.ApiVersion : VkontakteAuthenticationDefaults.ApiVersion }); if (Options.Fields.Count != 0) { address = QueryHelpers.AddQueryString(address, "fields", string.Join(",", Options.Fields)); } using var response = await Backchannel.GetAsync(address, 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 container = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); using var enumerator = container.RootElement.GetProperty("response").EnumerateArray(); var payload = enumerator.First(); var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload); context.RunClaimActions(); // Re-run to get the email claim from the tokens response context.RunClaimActions(tokens.Response.RootElement); await Options.Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal !, context.Properties, Scheme.Name)); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri) { var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string>() { ["appid"] = Options.ClientId, ["secret"] = Options.ClientSecret, ["code"] = code, ["grant_type"] = "authorization_code" }); HttpResponseMessage response = null; try { 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."))); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); if (!string.IsNullOrEmpty(payload.Value <string>("errcode"))) { 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."))); } return(OAuthTokenResponse.Success(payload)); } finally { response?.Dispose(); } }
protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, OAuthTokenResponse tokens) { var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, "access_token", tokens.AccessToken); address = QueryHelpers.AddQueryString(address, "v", Options.ApiVersion); if (Options.Fields.Count != 0) { address = QueryHelpers.AddQueryString(address, "fields", string.Join(",", Options.Fields)); } var response = await Backchannel.GetAsync(address, 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()); var user = (JObject)payload["response"][0]; foreach (var scope in Options.Scope) { var scope_value = tokens.Response.Value <string>(scope); if (!string.IsNullOrEmpty(scope_value)) { user.Add(scope, scope_value); } } var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, user); context.RunClaimActions(); await Options.Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
/// <summary> /// 创建身份票据(这是第三步) /// </summary> /// <param name="identity"></param> /// <param name="properties"></param> /// <param name="tokens"></param> /// <returns></returns> protected override async Task <AuthenticationTicket> CreateTicketAsync( ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var openId = GetOpenId(tokens.Response); var unionId = GetUnionId(tokens.Response); // 构造用户信息JsonElement var payloadDic = new Dictionary <string, object>() { ["openid"] = openId }; var userInfo = JsonDocument.Parse(JsonSerializer.Serialize(payloadDic)); //微信获取用户信息是需要开通权限的,没有开通权限的只能用openId来标示用户 if (!string.IsNullOrEmpty(unionId)) { //获取用户信息 var parameters = new Dictionary <string, string> { { "openid", openId }, { "access_token", tokens.AccessToken }, { "lang", "zh-CN" } //如果是多语言,这个参数该怎么获取? }; var userInfoEndpoint = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, parameters); var userInfoResponse = await Backchannel.GetAsync(userInfoEndpoint, Context.RequestAborted); if (!userInfoResponse.IsSuccessStatusCode) { throw new HttpRequestException( $"未能获取到微信用户个人信息(返回状态码:{userInfoResponse.StatusCode}),请检查access_token是正确。"); } userInfo = JsonDocument.Parse(await userInfoResponse.Content.ReadAsStringAsync()); } var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, userInfo.RootElement); context.RunClaimActions(); 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) { var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, "access_token", tokens.AccessToken); address = QueryHelpers.AddQueryString(address, "v", Options.ApiVersion); if (Options.Fields.Count != 0) { address = QueryHelpers.AddQueryString(address, "fields", string.Join(",", Options.Fields)); } var response = await Backchannel.GetAsync(address, 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()); var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload); var user = (JObject)payload["response"][0]; identity.AddOptionalClaim(ClaimTypes.NameIdentifier, VkontakteHelper.GetId(user), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.Name, VkontakteHelper.GetName(user), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.GivenName, VkontakteHelper.GetFirstName(user), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.Surname, VkontakteHelper.GetLastName(user), Options.ClaimsIssuer) .AddOptionalClaim(ClaimTypes.Hash, VkontakteHelper.GetHash(user), Options.ClaimsIssuer) .AddOptionalClaim("urn:vkontakte:photo:link", VkontakteHelper.GetPhoto(user), Options.ClaimsIssuer) .AddOptionalClaim("urn:vkontakte:photo_thumb:link", VkontakteHelper.GetPhotoThumbnail(user), Options.ClaimsIssuer); 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 identifier = WeChatHelper.GetId(tokens.Response); if (!string.IsNullOrEmpty(identifier)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:wechat:id", identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } var query = new QueryBuilder { { "access_token", tokens.AccessToken }, { "openid", identifier } }; var response = await Backchannel.GetAsync(Options.UserInformationEndpoint + query, Context.RequestAborted); response.EnsureSuccessStatusCode(); var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var notification = new OAuthCreatingTicketContext(Context, Options, Backchannel, tokens, payload) { Properties = properties, Principal = new ClaimsPrincipal(identity) }; var name = WeChatHelper.GetName(payload); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:wechat:name", name, ClaimValueTypes.String, Options.ClaimsIssuer)); } var img = WeChatHelper.GetHeadImage(payload); if (!string.IsNullOrEmpty(img)) { identity.AddClaim(new Claim("urn:wechat:headimgurl", img, ClaimValueTypes.String, Options.ClaimsIssuer)); } await Options.Events.CreatingTicket(notification); return(new AuthenticationTicket(notification.Principal, notification.Properties, notification.Options.AuthenticationScheme)); }
protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context) { var tokenRequestParameters = new Dictionary <string, string?>() { ["appid"] = Options.ClientId, ["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 address = QueryHelpers.AddQueryString(Options.TokenEndpoint, tokenRequestParameters); using var response = await Backchannel.GetAsync(address); if (!response.IsSuccessStatusCode) { await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } var json = await response.Content.ReadAsStringAsync(Context.RequestAborted); var payload = JsonDocument.Parse(json); var errorCode = payload.RootElement.GetString("errcode"); if (!string.IsNullOrEmpty(errorCode)) { Log.ExchangeCodeErrorCode(Logger, errorCode, response.Headers.ToString(), json); return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."))); } return(OAuthTokenResponse.Success(payload)); }