protected override async Task <AuthenticationTicket> CreateTicketAsync( ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { // Get the DingTalk user var timestamp = GetTimeStamp(); var requestUri = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase) { { "accessKey", Options.ClientId }, { "timestamp", timestamp }, { "signature", Signature(timestamp, Options.ClientSecret) } }); var requestContent = new StringContent(JsonSerializer.Serialize(new Dictionary <string, string> { { "tmp_auth_code", tokens.AccessToken } }), Encoding.UTF8, MediaTypeNames.Application.Json); var response = await Backchannel.PostAsync(requestUri, requestContent, Context.RequestAborted); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"An error occurred when retrieving DingTalk user information ({response.StatusCode}). Please check if the authentication information is correct."); } var responseContent = await response.Content.ReadAsStringAsync(); using var payload = JsonDocument.Parse(responseContent); int status = payload.RootElement.GetProperty("errcode").GetInt32(); 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.RootElement.GetString("errmsg")); throw new HttpRequestException("An error occurred while retrieving user information."); } var userInfo = payload.RootElement.GetProperty("user_info"); var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, userInfo); 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) { _logger?.LogDebug("CreateTicketAsync()"); HttpRequestMessage request = GetTokenInfoRequestMessage(tokens); HttpClient client = GetHttpClient(); HttpClientHelper.ConfigureCertificateValidatation( Options.ValidateCertificates, out SecurityProtocolType prevProtocols, out RemoteCertificateValidationCallback prevValidator); HttpResponseMessage response = null; try { response = await client.SendAsync(request, Context.RequestAborted); } finally { HttpClientHelper.RestoreCertificateValidation(Options.ValidateCertificates, prevProtocols, prevValidator); } if (!response.IsSuccessStatusCode) { _logger?.LogDebug("CreateTicketAsync() failure getting token info from {requesturi}", request.RequestUri); throw new HttpRequestException($"An error occurred when retrieving token information ({response.StatusCode})."); } var resp = await response.Content.ReadAsStringAsync(); _logger?.LogDebug("CreateTicketAsync() received json: {json}", resp); var payload = JObject.Parse(resp); var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload); context.RunClaimActions(); await Events.CreatingTicket(context); if (Options.UseTokenLifetime) { properties.IssuedUtc = CloudFoundryHelper.GetIssueTime(payload); properties.ExpiresUtc = CloudFoundryHelper.GetExpTime(payload); } await Events.CreatingTicket(context); var ticket = new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name); return(ticket); }
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(); } }
/// <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 <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, ["uid"] = tokens.Response.RootElement.GetString("uid") }); 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.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."); } using var payload = JsonDocument.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("email")) { string 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.RootElement); context.RunClaimActions(); await Options.Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
private static Task OnCreatingTicket(OAuthCreatingTicketContext context) { var handler = new JwtSecurityTokenHandler(); //Cognito stores user information and Claims in the id_token. var idToken = context.TokenResponse.Response["id_token"]; var jwtToken = handler.ReadJwtToken(idToken.ToString()); var appIdentity = new ClaimsIdentity(jwtToken.Claims); context.Principal.AddIdentity(appIdentity); return(Task.CompletedTask); }
private static async Task <JObject> GetDataFromEndPoint(OAuthCreatingTicketContext context, string url = default(string)) { var request = new HttpRequestMessage(HttpMethod.Get, string.IsNullOrWhiteSpace(url) ? context.Options.UserInformationEndpoint : url); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); return(JObject.Parse(await response.Content.ReadAsStringAsync())); }
private static async Task CreateGitHubAuthTicket(OAuthCreatingTicketContext context) { var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); var user = JObject.Parse(await response.Content.ReadAsStringAsync()); AddClaims(context, user); }
internal static Task OnCreatingTicket(OAuthCreatingTicketContext context) { if (context.Ticket.Principal != null) { Helpers.ThrowIfConditionFailed(() => context.AccessToken == "ValidAccessToken", "Access token is not valid"); Helpers.ThrowIfConditionFailed(() => context.RefreshToken == "ValidRefreshToken", "Refresh token is not valid"); Helpers.ThrowIfConditionFailed(() => context.ExpiresIn.Value == TimeSpan.FromSeconds(1200), "ExpiresIn is not valid"); Helpers.ThrowIfConditionFailed(() => context.User != null, "User object is not valid"); context.Ticket.Principal.Identities.First().AddClaim(new Claim("ManageStore", "false")); } return(Task.FromResult(0)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { string requestUri = Options.UserInformationEndpoint; var fields = Options.Fields .Where(f => !string.Equals(f, LinkedInAuthenticationConstants.EmailAddressField, StringComparison.OrdinalIgnoreCase)) .ToList(); // If at least one field is specified, append the fields to the endpoint URL. if (fields.Count > 0) { requestUri = QueryHelpers.AddQueryString(requestUri, "projection", $"({string.Join(',', fields)})"); } using var request = new HttpRequestMessage(HttpMethod.Get, requestUri); request.Headers.Add("x-li-format", "json"); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); using var response = await Backchannel.SendAsync(request, 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(); if (!string.IsNullOrEmpty(Options.EmailAddressEndpoint) && Options.Fields.Contains(LinkedInAuthenticationConstants.EmailAddressField)) { string?email = await GetEmailAsync(tokens); if (!string.IsNullOrEmpty(email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer)); } } 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) { if (string.IsNullOrEmpty(Options.Site)) { throw new InvalidOperationException( $"No site was specified for the {nameof(StackExchangeAuthenticationOptions.Site)} property of {nameof(StackExchangeAuthenticationOptions)}."); } var queryArguments = new Dictionary <string, string> { ["access_token"] = tokens.AccessToken, ["site"] = Options.Site, }; if (!string.IsNullOrEmpty(Options.RequestKey)) { queryArguments["key"] = Options.RequestKey; } string address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, queryArguments); 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.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."); } 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(payload.RootElement.GetProperty("items").EnumerateArray().First()); await Options.Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
/// <summary> /// <para> /// Registers or logs in a user if their Id can be found. /// </para> /// </summary> /// <param name="context"></param> /// <param name="Redis"></param> /// <param name="Settings"></param> /// <returns></returns> internal static async Task RegisterUser(OAuthCreatingTicketContext context, Startup.Provider LoginProvider /* change this later */, IDatabase Redis, AppSetting Settings) { // Retrieve user info by passing an Authorization header with the value token {accesstoken}; var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue(LoginProvider.AuthorizationHeader, context.AccessToken); // Extract the user info object from the OAuth response var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); var oauthres = await response.Content.ReadAsStringAsync(); if (Settings.Provider == "GitHub") { var GitHubProvider = new GitHubLoginProvider(Redis, Settings); // fetch the OAuth profile from the provider var user = await GitHubProvider.GetOAuthProfile(response, context); // Create the user from it var providerUser = GitHubProvider.CreateUserFromOAuth(user); // Register the profile var RegisteredUser = GitHubProvider.RegisterUser(providerUser); // Add the Name Identifier claim for htmlantiforgery tokens, and the users redis key location. context.Identity.AddClaims( new List <Claim> { new Claim( ClaimTypes.NameIdentifier, RegisteredUser.UserId.ToString(), ClaimValueTypes.String, context.Options.ClaimsIssuer ), new Claim( "RedisKey", $"{Settings.Redis.BaseKey}Users:{RegisteredUser.UserId}", ClaimValueTypes.String, context.Options.ClaimsIssuer ) } ); } else if (Settings.Provider == "Discord") { throw new NotImplementedException("Discord not really worth it"); var DiscordProvider = new DiscordLoginProvider(Redis, Settings); var a = await DiscordProvider.GetOAuthProfile(response, context); } }
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, "access_token", tokens.AccessToken); if (Options.UseSignedRequests) { // Compute the HMAC256 signature. var signature = ComputeSignature(address); // Add the signature to the query string. address = QueryHelpers.AddQueryString(address, "sig", signature); } 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()).Value <JObject>("data"); 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(); } }
/// <summary> /// CreateTicketAsync /// </summary> protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var parts = tokens.AccessToken.Split('.'); if (parts.Length < 2) { throw new HttpRequestException("An error occurred while retrieving the user profile. Incorrect access_token"); } string infoFromToken = Encoding.UTF8.GetString(Base64Decode(parts[1])); var esiaInfo = JsonConvert.DeserializeObject <EsiaInfo>(infoFromToken); var userIdentifier = esiaInfo.SbjId; if (string.IsNullOrEmpty(userIdentifier)) { throw new HttpRequestException("An error occurred while retrieving the user profile. Cannot get SbjId from token"); } var address = QueryHelpers.AddQueryString(string.Format(Options.UserInformationEndpoint, userIdentifier), new Dictionary <string, string>()); var response = await GetAsync(address, tokens.AccessToken); var content = await response.Content.ReadAsStringAsync(); 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: */ content); throw new HttpRequestException("An error occurred while retrieving the user profile."); } var payload = JObject.Parse(content); AddOptionalClaim(identity, ClaimTypes.NameIdentifier, userIdentifier, Options.ClaimsIssuer); AddOptionalClaim(identity, ClaimTypes.GivenName, payload.Value <string>("firstName"), Options.ClaimsIssuer); AddOptionalClaim(identity, ClaimTypes.Surname, payload.Value <string>("lastName"), Options.ClaimsIssuer); AddOptionalClaim(identity, ClaimTypes.Email, payload.Value <string>("email"), Options.ClaimsIssuer); var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload); 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) { string address = Options.UserInformationEndpoint; var fields = Options.Fields .Where(f => !string.Equals(f, LinkedInAuthenticationConstants.EmailAddressField, StringComparison.OrdinalIgnoreCase)) .ToList(); // If at least one field is specified, append the fields to the endpoint URL. if (fields.Count > 0) { address = QueryHelpers.AddQueryString(address, "projection", $"({string.Join(",", fields)})"); } var request = new HttpRequestMessage(HttpMethod.Get, address); request.Headers.Add("x-li-format", "json"); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); var response = await Backchannel.SendAsync(request, 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()); if (Options.Fields.Contains(LinkedInAuthenticationConstants.EmailAddressField)) { payload.Last.AddAfterSelf(new JProperty("emailAddress", await GetEmailAsync(tokens))); } 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)); }
/// <summary> /// 与本站通信同步 /// </summary> protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var message = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokens.AccessToken); var response = await Backchannel.SendAsync(message, 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 identifier = DoubanHelper.GetId(payload); if (!string.IsNullOrEmpty(identifier)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:douban:id", identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } var name = DoubanHelper.GetName(payload); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); identity.AddClaim(new Claim("urn:douban:name", name, ClaimValueTypes.String, Options.ClaimsIssuer)); } var avatar = DoubanHelper.GetAvatar(payload); if (!string.IsNullOrEmpty(avatar)) { identity.AddClaim(new Claim("urn:douban:avatar", avatar, ClaimValueTypes.String, Options.ClaimsIssuer)); } var uid = DoubanHelper.GetUid(payload); if (!string.IsNullOrEmpty(uid)) { identity.AddClaim(new Claim("urn:douban:uid", uid, ClaimValueTypes.String, Options.ClaimsIssuer)); } await Options.Events.CreatingTicket(notification); return(new AuthenticationTicket(notification.Principal, notification.Properties, notification.Options.AuthenticationScheme)); }
public async Task GetUser(OAuthCreatingTicketContext context, string provider) { var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); request.Headers.Add("x-li-format", "json"); // Tell LinkedIn we want the result in JSON, otherwise it will return XML var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); var user = JObject.Parse(await response.Content.ReadAsStringAsync()); AddClaims(context, user, provider); }
/// <inheritdoc /> protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { var parameters = new KeyValuePair <string, string>[] { #if NETSTANDARD2_0_OR_GREATER new("id_token", tokens.Response.Value <string>("id_token") ?? string.Empty), #else new("id_token", tokens.Response?.RootElement.GetString("id_token") ?? string.Empty), #endif new("client_id", this.Options.ClientId), }; using var request = new HttpRequestMessage(HttpMethod.Post, this.Options.UserInformationEndpoint); using var httpContent = new FormUrlEncodedContent(parameters !); request.Content = httpContent; request.Headers.Accept.Add(new("application/json")); using var response = await this.Backchannel.SendAsync(request, this.Context.RequestAborted).ConfigureAwait(false); #if NET5_0_OR_GREATER var payload = await response.Content.ReadAsStringAsync(this.Context.RequestAborted).ConfigureAwait(false); #else var payload = await response.Content.ReadAsStringAsync().ConfigureAwait(false); #endif if (!response.IsSuccessStatusCode) { var headers = response.Headers.ToString(); this.Logger.LogError("An error occurred while verifying the ID token. The remote server returned a {Status} response with the following payload: {Headers} {Body}.", response.StatusCode, headers, payload); #if NET5_0_OR_GREATER throw new HttpRequestException("An error occurred while verifying the ID token.", null, response.StatusCode); #else throw new HttpRequestException("An error occurred while verifying the ID token.", null); #endif } var principal = new ClaimsPrincipal(identity); #if NETSTANDARD2_0_OR_GREATER var user = JObject.Parse(payload); var context = new OAuthCreatingTicketContext(principal, properties, this.Context, this.Scheme, this.Options, this.Backchannel, tokens, user); #else using var json = JsonDocument.Parse(payload); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, json.RootElement); #endif context.RunClaimActions(); await this.Events.CreatingTicket(context).ConfigureAwait(false); return(new(context.Principal !, context.Properties, this.Scheme.Name)); }
public Task OnCreatingTicketFuncAsync(OAuthCreatingTicketContext ctx) { // Get "State" property ctx.Properties.Items.TryGetValue("state", out var stateValue); if (string.IsNullOrWhiteSpace(stateValue)) { // Fail auth if state property is missing ctx.Fail("Discord Token JWT was missing in the 'State' parameter of the authentication request"); return(Task.CompletedTask); } ctx.Principal.Identities.First().AddClaim(new Claim("ReferralTokenId", stateValue)); return(Task.CompletedTask); }
/// <inheritdoc /> protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { await ProcessIdTokenAsync(tokens, properties, identity); var principal = new ClaimsPrincipal(identity); var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, JsonDocument.Parse("{}").RootElement); 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 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(); } }
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 payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload); // 填充openid payload["openid"] = openId; context.RunClaimActions(); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); }
private async Task <string> GetSeasonIdAsync(OAuthCreatingTicketContext context) { var request = new HttpRequestMessage( HttpMethod.Get, "https://eu.api.blizzard.com/sc2/ladder/season/2" + "?access_token=" + context.AccessToken ); var response = await GetResponseAsync(request, context); var jObject = JObject.Parse(response); return((string)jObject["seasonId"]); }
/// <summary> /// Call the OAuthServer and get a user's information. /// The context object will have the Identity, AccessToken, and UserInformationEndpoint available. /// Using this information, we can query the auth server for claims to attach to the identity. /// A particular OAuthServer's endpoint returns a json object with a roles member and a name member. /// We call this endpoint with HttpClient, parse the result, and attach the claims to the Identity. /// </summary> /// <param name="identity"></param> /// <param name="properties"></param> /// <param name="tokens"></param> /// <returns></returns> protected virtual async Task <AuthenticationTicket> CreateTicketAsync( ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { if (identity == null) { throw new ArgumentNullException(nameof(identity)); } if (properties == null) { throw new ArgumentNullException(nameof(properties)); } if (tokens == null) { throw new ArgumentNullException(nameof(tokens)); } var unionid = tokens.GetUnionId(); var openid = tokens.GetOpenId(); var scope = tokens.GetScope(); var payload = JsonDocument.Parse("{}"); if (/*WeixinAuthScopes.Contains(Options.Scope, WeixinAuthScopes.Items.snsapi_userinfo) || */WeixinAuthScopes.Contains(scope, WeixinAuthScopes.snsapi_userinfo)) { payload = await _api.GetUserInfo(Options.Backchannel, Options.UserInformationEndpoint, tokens.AccessToken, openid, Context.RequestAborted, WeixinAuthLanguageCodes.zh_CN); } //if (!payload.RootElement.GetString("unionid") ) //{ // payload.Add("unionid", unionid); //} //if (!payload.ContainsKey("openid") && !string.IsNullOrWhiteSpace(openid)) //{ // payload.Add("openid", openid); //} //payload.Add("scope", scope); payload.AppendElement("scope", scope); 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 address = Options.UserInformationEndpoint; // If at least one field is specified, // append the fields to the endpoint URL. if (Options.Fields.Count != 0) { address = address.Insert(address.LastIndexOf("~") + 1, $":({ string.Join(",", Options.Fields)})"); } HttpRequestMessage request = null; HttpResponseMessage response = null; try { request = new HttpRequestMessage(HttpMethod.Get, address); request.Headers.Add("x-li-format", "json"); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); response = await Backchannel.SendAsync(request, 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 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(); } }
protected override async Task <AuthenticationTicket> CreateTicketAsync([NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { // Note: the ArcGIS API doesn't support content negotiation via headers. var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string> { ["f"] = "json", ["token"] = tokens.AccessToken }); HttpRequestMessage request = null; HttpResponseMessage response = null; try { request = new HttpRequestMessage(HttpMethod.Get, address); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // Request the token response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); // Note: error responses always return 200 status codes. var error = payload.Value <JObject>("error"); if (error != null) { // See https://developers.arcgis.com/authentication/server-based-user-logins/ for more information Logger.LogError("An error occurred while retrieving the user profile: the remote server " + "returned a response with the following error code: {Code} {Message}.", /* Code: */ error.Value <string>("code"), /* Message: */ error.Value <string>("message")); throw new InvalidOperationException("An error occurred while retrieving the user profile."); } 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(); } }
/// <summary> /// 插入 Gitee 授权用户到数据库中 /// </summary> /// <param name="context"></param> /// <returns></returns> private static User ParseUser(OAuthCreatingTicketContext context) { var user = context.User.ToObject <WeChatUser>(); return(new User() { ApprovedBy = "OAuth", ApprovedTime = DateTime.Now, DisplayName = user.NickName, UserName = user.UnionId, Password = LgbCryptography.GenerateSalt(), Icon = user.HeadImgUrl, Description = $"{context.Scheme.Name}" }); }
/// <summary> /// 插入 Gitee 授权用户到数据库中 /// </summary> /// <param name="context"></param> /// <returns></returns> private static User ParseUser(OAuthCreatingTicketContext context) { var user = context.User.ToObject <OAuthUser>(); return(new User() { ApprovedBy = "OAuth", ApprovedTime = DateTime.Now, DisplayName = user?.Name ?? "", UserName = user?.Login ?? "", Password = LgbCryptography.GenerateSalt(), Icon = user?.Avatar_Url ?? "", Description = $"{context.Scheme.Name}({user?.Id})" }); }
public static async Task <string> GetIdentityPayload(this OAuthCreatingTicketContext context) { var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); var payload = await response.Content.ReadAsStringAsync(); return(payload); }