/// <summary> /// Builds a XeroLogin URL for code flow, allows state and scope to be passed in. /// </summary> /// <returns>A valid initial redirect URI for Xero OAuth 2.0 authorisation flow.</returns> public string BuildLoginUri(string state, string scope) { var url = _xeroAuthorizeUri.CreateAuthorizeUrl( clientId: xeroConfiguration.ClientId, responseType: "code", redirectUri: xeroConfiguration.CallbackUri.AbsoluteUri, state: state, scope: scope ); return(url); }
protected async Task <string> DefaultGetAuthorizationCode(string authorizationEndpoint) { CurrentStateToken = GenerateAuthorizationStateToken(); var request = new RequestUrl(authorizationEndpoint); var authorizeUri = request.CreateAuthorizeUrl(ClientId, OidcConstants.ResponseTypes.Code, Scope, RedirectUriRoot, CurrentStateToken); var redirectUri = await AuthUriAcquirer.GetAuthorizationUriAsync(authorizeUri, RedirectUriRoot); if (string.IsNullOrEmpty(redirectUri)) { return(null); } var returnedStateToken = StateCodeRegex.Match(redirectUri).Groups[1].Value; if (returnedStateToken != CurrentStateToken) { return(null); } var authCode = AuthCodeRegex.Match(redirectUri).Groups[1].Value; authCode = WebUtility.UrlDecode(authCode); return(authCode); }
public ViewResult Login([FromQuery] string returnUrl) { var authorizeEndpoint = $"{_generalSettings.Authority}/connect/authorize"; var requestUrl = new RequestUrl(authorizeEndpoint); var codeVerifier = CryptoRandom.CreateUniqueId(32); if (TempData.ContainsKey(OidcConstants.TokenRequest.CodeVerifier)) { TempData.Remove(OidcConstants.TokenRequest.CodeVerifier); } TempData.Add(OidcConstants.TokenRequest.CodeVerifier, codeVerifier); string codeChallenge; using (var sha256 = SHA256.Create()) { var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier)); codeChallenge = Base64Url.Encode(challengeBytes); } var authorizeUrl = requestUrl.CreateAuthorizeUrl( clientId: _clientSettings.Id, responseType: OidcConstants.ResponseTypes.CodeIdToken, codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256, codeChallenge: codeChallenge, responseMode: OidcConstants.ResponseModes.FormPost, redirectUri: $"{_generalSettings.Host}/account/auth-callback", nonce: Guid.NewGuid().ToString(), scope: string.Join(" ", _clientSettings.Scopes), state: !string.IsNullOrEmpty(returnUrl) ? Convert.ToBase64String(Encoding.UTF8.GetBytes(returnUrl)) : null ); return(View(new LoginViewModel { AuthorizeUrl = authorizeUrl })); }
public async Task <string> AuthenticateExternalUser(string clientId) { try { var idToken = this.Request.Headers["id"]; if (string.IsNullOrEmpty(idToken)) { throw new Exception("No ID Token supplied"); } var requestUrl = new RequestUrl(Addresses.InoxicoSTSAuth); var redirectUrl = requestUrl.CreateAuthorizeUrl( clientId: OAuth.InoxicoClientId, responseType: "id_token token", scope: "openid profile read write offline_access", redirectUri: Addresses.IntendedLocation, state: EncodeState(idToken, clientId), nonce: Guid.NewGuid().ToString("N"), acrValues: $"idp:{OAuth.IdentityProvider_ThirdParty}"); return(redirectUrl); } catch (Exception ex) { throw; } }
/// <summary> /// Uses the Embedded Broswer for login and auto process the AccessCode /// </summary public async Task <BrowserResultType> SignIn(OAuthSettings oAuthApplication, OAuthToken token) { var request = new RequestUrl(authorizationUrl); var url = request.CreateAuthorizeUrl( clientId: oAuthApplication.ClientID, responseType: OidcConstants.ResponseTypes.Code, scope: _scope, state: oAuthApplication.ApplicationID.ToString(), redirectUri: oAuthApplication.ReturnUrl); var Browser = new HMRC.Browser.WinFormsBroswer(); var browserOptions = new BrowserOptions(url, "", SuccessTitle); browserOptions.DisplayMode = DisplayMode.Visible; var browserResult = await Browser.InvokeAsync(browserOptions); if (browserResult.ResultType == BrowserResultType.Success) { var r = browserResult.Response.Split('&'); Dictionary <String, String> p = new Dictionary <string, string>(); foreach (var item in r) { var r1 = item.Split('='); p.Add(r1[0], r1[1]); } string code = p[SuccessTitle]; ProcessAuthorizationCode(code, oAuthApplication, token); } return(browserResult.ResultType); }
public Uri GetLoginUri(Uri redirectUri, string state) { var request = new RequestUrl(authorizationEndpoint); var lower = string.Join(" ", scopes).ToLower(); var absoluteUri = redirectUri.AbsoluteUri; var state1 = state.NullIfEmptyOrWhitespace(); var nonce = Guid.NewGuid().ToString("N"); return(new Uri(request.CreateAuthorizeUrl(clientId, "id_token", lower, absoluteUri, state1, nonce, responseMode: "form_post"))); }
/// <summary> /// Builds a XeroLogin URL /// </summary> /// <returns>valid URI for login</returns> public string BuildLoginUri() { var url = xeroAuthorizeUri.CreateAuthorizeUrl( clientId: xeroConfiguration.ClientId, responseType: "code", //hardcoded authorisation code for now. redirectUri: xeroConfiguration.CallbackUri.AbsoluteUri, state: xeroConfiguration.State, scope: xeroConfiguration.Scope ); return(url); }
protected string GetAuthenticationURL() { var ru = new RequestUrl($"http://{Backend.BASE_URL}/connect/authorize"); var url = ru.CreateAuthorizeUrl( clientId: "clientApp", responseType: "code id_token", redirectUri: "https://localhost/signin-oidc", nonce: "xyz", scope: "openid offline_access profile resourceApi"); return(url); }
private string GetLoginUrl(string redirectUrl, string nonce, string state) { var config = GetOpenIdConnectConfiguration(); var requestUrl = new RequestUrl(config.AuthorizationEndpoint); return(requestUrl.CreateAuthorizeUrl(GetAttributeValue(AttributeKey.ApplicationId), OidcConstants.ResponseTypes.Code, GetScopes(), $"{redirectUrl}", state, nonce)); }
public void OnGet() { var xeroAuthorizeUri = new RequestUrl("https://login.xero.com/identity/connect/authorize"); var url = xeroAuthorizeUri.CreateAuthorizeUrl( clientId: GlobalConstant.ClientId, responseType: "code", //hardcoded authorisation code for now. redirectUri: GlobalConstant.RedirectUrl, state: "your state", scope: "openid profile email files accounting.transactions accounting.transactions.read accounting.reports.read accounting.journals.read accounting.settings accounting.settings.read accounting.contacts accounting.contacts.read accounting.attachments accounting.attachments.read offline_access" ); ViewData["XeroAuthorizeUrl"] = url; }
/// <summary> /// Gets the token. /// </summary> /// <returns>System.String.</returns> public string GetToken() { var xeroAuthorizeUri = new RequestUrl(XeroUrl.IdentityServerAuthorize); var url = xeroAuthorizeUri.CreateAuthorizeUrl( clientId: _settings.ClientId, responseType: "code", //hardcoded authorisation code for now. redirectUri: "https://localhost:5001/oauth", state: "", scope: "openid profile email files accounting.transactions accounting.transactions.read accounting.reports.read accounting.journals.read accounting.settings accounting.settings.read accounting.contacts accounting.contacts.read accounting.attachments accounting.attachments.read offline_access" ); return(url); }
internal string GenerateAuthorizationCodeUrl() { var authorizeEndpointUrl = new RequestUrl(this.ApplicationConfiguration.AuthorizeEndpoint); var url = authorizeEndpointUrl.CreateAuthorizeUrl( clientId: this.ApplicationConfiguration.ClientId, scope: this.ApplicationConfiguration.Scope, responseType: OidcConstants.ResponseTypes.Code, responseMode: OidcConstants.ResponseModes.Fragment, redirectUri: this.ApplicationConfiguration.RedirectUri, state: CryptoRandom.CreateUniqueId(), nonce: CryptoRandom.CreateUniqueId()); return(url); }
/// <summary> /// Created a Login URL incase you want to Call a different Browser from SignIn() /// </summary> public string GetSigninURL(OAuthSettings oAuthApplication) { var request = new RequestUrl(authorizationUrl); var url = request.CreateAuthorizeUrl( clientId: oAuthApplication.ClientID, responseType: OidcConstants.ResponseTypes.Code, scope: _scope, state: oAuthApplication.ApplicationID.ToString(), redirectUri: oAuthApplication.ReturnUrl); //Wish I could send this in! //UserName = oAuthApplication.UserID, //Password = oAuthApplication.Password, return(url); }
/// <summary> /// Creates the authorization request and shows the popup with the Web View. /// When the login is succesfully complete triggers you the LoginDone event. /// </summary> public void Login(string scope, string responseType) { const string redirectUri = "oob://localhost/wpf.webview.client"; var request = new RequestUrl($"{AppSettings.Settings.Endpoint}identity/connect/authorize"); var startUrl = request.CreateAuthorizeUrl( clientId: AppSettings.Settings.ClientId, responseType: responseType, scope: scope, redirectUri: redirectUri, nonce: CryptoRandom.CreateUniqueId()); _login = new LoginWebView(); _login.Done += _login_Done; _login.Show(); _login.Start(new Uri(startUrl), new Uri(redirectUri)); }
public ContentResult Get() { var xeroAuthorizeUri = new RequestUrl("https://login.xero.com/identity/connect/authorize"); var url = xeroAuthorizeUri.CreateAuthorizeUrl( clientId: clientId, responseType: "code", //hardcoded authorisation code for now. redirectUri: redirectUrl, state: "your state", scope: "openid profile email files accounting.transactions accounting.transactions.read accounting.reports.read accounting.journals.read accounting.settings accounting.settings.read accounting.contacts accounting.contacts.read accounting.attachments accounting.attachments.read offline_access" ); return(new ContentResult { ContentType = "text/html", StatusCode = (int)HttpStatusCode.OK, Content = String.Format("<html><head></head><body><a href ='{0}'>Connect to Xero</a></body></html>", url) }); }
/// <summary> /// 远程登录 /// </summary> /// <returns></returns> public async Task <ActionResult> RemoteLogin() { var client = new DiscoveryClient("http://10.37.11.12:7000"); client.Policy.RequireHttps = false; var doc = await client.GetAsync(); var request = new RequestUrl(doc.AuthorizeEndpoint); var url = request.CreateAuthorizeUrl( clientId: "netfx.client4", responseType: OidcConstants.ResponseTypes.CodeIdToken, responseMode: OidcConstants.ResponseModes.FormPost, redirectUri: "http://10.37.11.12:6004/Home/CallBack", scope: "netfx.api.TEST netcore.api.TEST openid", state: CryptoRandom.CreateUniqueId(), nonce: CryptoRandom.CreateUniqueId()); return(Redirect(url));//302重定向到远程服务器登录 }
public async Task <bool> SignOut(string accessToken) { var result = false; var introspection = await IdentityIntrospectionService.IntrospectToken(accessToken); var discovery = await DiscoveryService.GetDiscovery(); var requestUrl = new RequestUrl(discovery.AuthorizeEndpoint); var url = requestUrl.CreateAuthorizeUrl(Config.ClientId, "id_token", "openid email TSAPI"); using (var client = new HttpClient()) { var response = await client.GetAsync(url); result = response.StatusCode == System.Net.HttpStatusCode.OK; } return(result); }
private async Task <TokenResponse> TestAuthCode(ClientConfig clientConfig, HttpClient client, string discoTokenEndpoint, string discoAuthorizeEndpoint) { var ru = new RequestUrl(discoAuthorizeEndpoint); string codeVerifier = CryptoRandom.CreateUniqueId(50); string codeChallenge; using (var sha256 = SHA256.Create()) { var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier)); codeChallenge = Base64Url.Encode(challengeBytes); } var url = ru.CreateAuthorizeUrl( codeChallenge: codeChallenge, codeChallengeMethod: "S256", clientId: clientConfig.Id, responseType: "code", redirectUri: clientConfig.RedirectUris[0], scope: string.Join(" ", clientConfig.AllowedScopes)); OpenUrl(url); _logger.LogInformation(url); //dopo il login l'utente viene rediretto alla pagina del redirectUri e tra i parametri in querystring c'è il code _logger.LogInformation("insert code:"); var code = Console.ReadLine(); if (string.IsNullOrWhiteSpace(code)) { code = "code_missing"; } return(await client.RequestAuthorizationCodeTokenAsync( new AuthorizationCodeTokenRequest { Address = discoTokenEndpoint, ClientId = clientConfig.Id, ClientSecret = clientConfig.Password, RedirectUri = clientConfig.RedirectUris[0], Code = code, CodeVerifier = codeVerifier })); }
public async Task <IActionResult> LoginImplicitGrant(LoginViewModel model, string state, string client_id, string response_type, string scope, string returnUrl) { ViewData["ReturnUrl"] = returnUrl; if (ModelState.IsValid) { var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : false); if (result.Succeeded) { _logger.LogInformation("User logged in."); //Change for proper domain var request = new RequestUrl("https://0c574e90.ngrok.io/connect/authorize"); var url = request.CreateAuthorizeUrl( clientId: "alexa", scope: scope, responseType: OidcConstants.ResponseTypes.IdTokenToken, redirectUri: returnUrl, state: state, nonce: CryptoRandom.CreateUniqueId()); //returnUrl + "#state=" + state + "&access_token=" + "&token_type=" return(Redirect(url)); } if (result.RequiresTwoFactor) { return(RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe })); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return(RedirectToAction(nameof(Lockout))); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return(View(model)); } } // If we got this far, something failed, redisplay form return(View(model)); }
/// <inheritdoc cref="IUserApiClient.SigninAsync" /> public async Task SigninAsync() { var pkce = crypto.CreatePkceData(); var disco = await cache.GetAsync(); var url = new RequestUrl(disco.AuthorizeEndpoint); var auth = url.CreateAuthorizeUrl( options.ClientId, OidcConstants.ResponseTypes.Code, GetScopes(options.Scopes), options.RedirectUri, state: pkce.CodeVerifier, responseMode: OidcConstants.ResponseModes.Query, codeChallenge: pkce.CodeChallenge, codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256, uiLocales: CultureInfo.CurrentUICulture.EnglishName ); uri.NavigateTo(auth); }
public async Task <string> CreateAuthorizeUrlAsync(Microsoft.Bot.Connector.IActivity activity) { var doc = await GetDiscoveryClient(); var request = new RequestUrl(doc.AuthorizeEndpoint); var extra = new Dictionary <string, string> { { OidcConstants.TokenRequest.ClientSecret, "secret" } }; var authorizeUrl = request.CreateAuthorizeUrl( clientId: "Bot", responseType: OidcConstants.ResponseTypes.CodeIdToken, responseMode: OidcConstants.ResponseModes.FormPost, redirectUri: signinUrl, scope: "openid profile offline_access orders basket marketing locations", state: AuthData.Encode(activity.Recipient.Id, activity.ChannelId, activity.From.Id, activity.Conversation.Id, activity.ServiceUrl), nonce: CryptoRandom.CreateUniqueId(), extra: extra); return(authorizeUrl); }
public async Task <string> AuthorizeUrl() { using (HttpClient client = httpClientFactory.CreateClient()) { DiscoveryResponse disco = await client.GetDiscoveryDocumentAsync(Utils.Linked.Identity); if (disco.IsError) { return(null); } var ru = new RequestUrl(disco.AuthorizeEndpoint); string url = ru.CreateAuthorizeUrl( clientId: Utils.IdentityClient.ClientId, responseType: "code", scope: "openid profile email api", redirectUri: Utils.ClientIdentityRedirectUri ); return(url); } }
//https://auth0.com/docs/flows/concepts/auth-code-pkce public async Task <(string AuthorizeUrl, string CodeVerifier)> CreateAuthorizeUrlAsync(HttpContext context) { await LoadEndpointsAsync(); var originalPathBase = context.Features.Get <IAuthenticationFeature>()?.OriginalPathBase ?? context.Request.PathBase; var redirectUri = context.Request.Scheme + "://" + context.Request.Host + originalPathBase + signedInCallbackPath; var ru = new RequestUrl(authorizeEndpoint); var pkce = GeneratePKCEValues(); var url = ru.CreateAuthorizeUrl( clientId: clientId, responseType: responseType, redirectUri: redirectUri, nonce: CryptoRandom.CreateUniqueId(32), codeChallengeMethod: pkce.CodeChallengeMethod, codeChallenge: pkce.CodeChallenge, scope: scopes); return(url, pkce.CodeVerifier); }
private void PrepareAuthorizeRequest(DiscoveryDocumentResponse disco, out string codeVerifier, out string authorizeUrl) { var cvBytes = GetCodeVerifier(); codeVerifier = Encoding.UTF8.GetString(cvBytes); var codeChallenge = GetCodeChallenge(cvBytes); var nonce = GetNonce(); var state = GetState(); var ru = new RequestUrl(disco.AuthorizeEndpoint); authorizeUrl = ru.CreateAuthorizeUrl( clientId: _oidcOptions.ClientId, responseType: _oidcOptions.ResponseType, redirectUri: $"{ _oidcOptions.RedirectUri}", nonce: nonce, state: state, codeChallenge: codeChallenge, codeChallengeMethod: _oidcOptions.CodeChallengeMethod, scope: string.Join(" ", _oidcOptions.Scopes) ); }
static async Task AuthorizeUrl() { try { var codeVerifier = CryptoRandom.CreateUniqueId(32); var stateVerifier = CryptoRandom.CreateUniqueId(32); var nonceVerifier = CryptoRandom.CreateUniqueId(32); // discover endpoints from metadata var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("https://localhost:44303/"); if (disco.IsError) { Console.WriteLine(disco.Error); return; } var ru = new RequestUrl("https://localhost:44303/connect/authorize"); var authorizeUrl = ru.CreateAuthorizeUrl(clientId: "d84d0a966e0b470facebd7a6dfa8b6b1", responseType: "code", scope: "openid profile offline_access awesomecareapi", redirectUri: "https://localhost:44372/signin-oidc", responseMode: "form_post", codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256, codeChallenge: codeVerifier.ToSha256(), state: stateVerifier.ToSha256(), nonce: nonceVerifier.ToSha256() ); } catch (Exception ex) { throw; } }
public static void RedirectToAuthority(string returnUrl) { var authorizeEndpoint = $"{OAuthConfiguration.Authority}/{OAuthConfiguration.AuthorizeEndpointPath}"; var stateProvider = new StateProvider <string>(); var currentPath = returnUrl ?? string.Empty; var requestUrl = new RequestUrl(authorizeEndpoint); // Create the url to Identity Server's authorize endpoint. var authorizeUrl = requestUrl.CreateAuthorizeUrl( clientId: OAuthConfiguration.ClientId, responseType: (OAuthConfiguration.ResponseType == "CodeIdToken")? OidcConstants.ResponseTypes.CodeIdToken : OidcConstants.ResponseTypes.Code, redirectUri: $"{OAuthConfiguration.Host}/SignInOidc.ashx", nonce: Guid.NewGuid().ToString(), // Identity Server will echo back the nonce value in the identity token (this is for replay protection). scope: OAuthConfiguration.Scopes.Join(" "), state: stateProvider.CreateState(currentPath) ); if (!HttpContext.Current.Response.IsRequestBeingRedirected) { // Redirect the user to the authority. HttpContext.Current.Response.Redirect(authorizeUrl); } HttpContext.Current.ApplicationInstance.CompleteRequest(); }
public async Task <IActionResult> OnGetOrPost() { if (string.IsNullOrWhiteSpace(Issuer)) { _logger.LogError(new ArgumentNullException(nameof(Issuer)), $"{nameof(Issuer)} is missing."); return(BadRequest()); } if (string.IsNullOrWhiteSpace(LoginHint)) { _logger.LogError(new ArgumentNullException(nameof(LoginHint)), $"{nameof(LoginHint)} is missing."); return(BadRequest()); } if (string.IsNullOrWhiteSpace(LtiMessageHint)) { _logger.LogError(new ArgumentNullException(nameof(LtiMessageHint)), $"{nameof(LtiMessageHint)} is missing."); return(BadRequest()); } if (string.IsNullOrWhiteSpace(TargetLinkUri)) { _logger.LogError(new ArgumentNullException(nameof(TargetLinkUri)), $"{nameof(TargetLinkUri)} is missing."); return(BadRequest()); } // Get the platform settings var platform = await _context.GetPlatformByIssuerAsync(Issuer); if (platform == null) { _logger.LogError($"Issuer not found [{Issuer}]."); return(BadRequest()); } // RPs MUST verify the value of the target_link_uri to prevent being // used as an open redirector to external sites. if (!Uri.TryCreate(TargetLinkUri, UriKind.Absolute, out var targetLinkUri)) { _logger.LogError($"Invalid target_link_uri [{TargetLinkUri}]."); return(BadRequest()); } if (targetLinkUri.Host != Request.Host.Host) { _logger.LogError($"Invalid target_link_uri [{TargetLinkUri}]."); return(BadRequest()); } // Create a unique nonce for this flow var nonce = CryptoRandom.CreateUniqueId(); // Consider using a state JWT as described in // https://tools.ietf.org/html/draft-bradley-oauth-jwt-encoded-state-09 var state = CryptoRandom.CreateUniqueId(); // Store the nonce and flow so they can be validated when the id_token // is posted back to the tool by the Authorization Server. _stateContext.AddState(nonce, state); var ru = new RequestUrl(platform.AuthorizeUrl); var url = ru.CreateAuthorizeUrl ( clientId: platform.ClientId, responseType: OidcConstants.ResponseTypes.IdToken, // POST the id_token directly to the tool's launch URL responseMode: OidcConstants.ResponseModes.FormPost, redirectUri: TargetLinkUri, // Per IMS guidance scope: OidcConstants.StandardScopes.OpenId, // Consider checking state after redirect to make sure the state was not tampared with state: state, // The userId loginHint: LoginHint, // Checking nonce at launch to make sure the id_token came from this flow and not direct nonce: nonce, // No user interaction prompt: "none", // The messagedId (i.e. resource link id or deep link id) extra: new { lti_message_hint = LtiMessageHint } ); _logger.LogInformation("Requesting id_token."); return(Redirect(url)); }
public static string getUrl(ulong id, Action <MSScopeOptions> action = null) { var msScope = new MSScopeOptions(); if (action == null) { action = x => { x.OpenId = true; x.User_Read = true; } } ; action(msScope); string stateValue = id.ToString(); stateValue += "." + Program.ToBase64(msScope.ToString()); var ru = new RequestUrl($"https://login.microsoftonline.com/{Program.Configuration["ms_auth:tenant_id"]}/oauth2/v2.0/authorize"); var url = ru.CreateAuthorizeUrl( clientId: Program.Configuration["ms_auth:client_id"], responseType: "id_token code", responseMode: "form_post", redirectUri: Handler.LocalAPIUrl + "/login/msoauth", nonce: DateTime.Now.DayOfYear.ToString(), state: stateValue, scope: msScope.GetScopes()); Console.WriteLine(url); return(url); } bool actOnUserProfile(TokenResponse response, HttpClient client) { var request = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me"); request.Headers.Add("Authorization", "Bearer " + response.AccessToken); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var identityResponse = client.SendAsync(request).Result; if (!identityResponse.IsSuccessStatusCode) { RespondRaw("Could not complete Oauth", identityResponse.StatusCode); return(false); } var content = identityResponse.Content.ReadAsStringAsync().Result; var jobj = JObject.Parse(content); Context.User.VerifiedEmail = jobj["mail"].ToObject <string>(); Context.User.IsVerified = true; if (string.IsNullOrWhiteSpace(Context.User.Name) || Context.User.Name == Context.User.Id.ToString()) { Context.User.OverrideName = jobj["displayName"].ToObject <string>(); } var service = Program.Services.GetRequiredService <ChessService>(); if (service != null && !Context.User.ServiceUser && !Context.User.GeneratedUser) { using var db = Program.Services.GetRequiredService <ChessDbContext>(); string name = $"{jobj["givenName"]} {jobj["surname"].ToObject<string>()[0]}"; var existing = db.Players.AsQueryable().FirstOrDefault(x => x.Name == name && !x.IsBuiltInAccount); if (existing != null) { existing.ConnectedAccount = Context.User.Id; } else { var chs = db.Players.AsQueryable().FirstOrDefault(x => x.DiscordAccount == ChessService.cast(Context.User.Id) && !x.IsBuiltInAccount); if (chs != null) { chs.Name = name; } } service.OnSave(); } return(true); } bool actOnTeams(TokenResponse response, HttpClient client) { var teamsRequest = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/joinedTeams"); teamsRequest.Headers.Add("Authorization", "Bearer " + response.AccessToken); teamsRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var teamsResponse = client.SendAsync(teamsRequest).Result; if (!teamsResponse.IsSuccessStatusCode) { RespondRaw("Could not retrieve your teams information", teamsResponse.StatusCode); return(false); } var content = teamsResponse.Content.ReadAsStringAsync().Result; var jobj = JObject.Parse(content); var jvalue = jobj["value"]; var teamsArray = (JArray)jvalue; Dictionary <string, string> classes = new Dictionary <string, string>(); foreach (JToken jTeam in teamsArray) { var name = jTeam["displayName"].ToObject <string>(); var split = name.Split('-'); if (split.Length != 2) { continue; } // class - Subject // eg // 1Mt3 - Maths classes[split[0].Trim()] = split[1].Trim(); } Context.User.Classes = classes; return(true); }
public async Task <TokenResponse> Login(LoginSettings loginSettings) { _log($"Logging in user {loginSettings.UserName} to {loginSettings.Authority}"); var httpClient = new HttpClient( // We're following the auto-redirects explicitly. // The http client handler can also follow redirects, but then we can't intercept the request to the return url. new AutoFollowRedirectHandler( // Handler that intercepts the requests to the return url, so the return url // doesn't actually have to be valid (just registered with auth0) new InterceptRedirectBackHandler( loginSettings.RedirectUri.Host, // Actual http handler that invokes auth0 new HttpClientHandler() ) ) ); // Retrieve the discovery document. In theory we could hard-code the url's, // but this follows the standards better. var disco = await httpClient.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest() { Address = loginSettings.Authority.ToString(), }); if (disco.IsError) { // Verify that the authority is available" throw new InvalidOperationException($"Failed to access authority discovery document: {disco.HttpStatusCode}: {disco.Error}"); } // Step 1: Create and go to authorize url var request = new RequestUrl(disco.AuthorizeEndpoint); var cryptoHelper = new CryptoHelper(); var pkce = cryptoHelper.CreatePkceData(); var clientId = loginSettings.ClientId; var authorizeUrl = request.CreateAuthorizeUrl( clientId, OidcConstants.ResponseTypes.Code, responseMode: OidcConstants.ResponseModes.Query, redirectUri: loginSettings.RedirectUri.ToString(), codeChallenge: pkce.CodeChallenge, codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256, scope: string.Join(" ", loginSettings.Scopes), extra: new { audience = loginSettings.Audience }); _log(" - Login Step 1: Create and go to authorize url: " + authorizeUrl); var response = await httpClient.GetAsync(authorizeUrl); if (response.StatusCode != HttpStatusCode.OK) { throw new InvalidOperationException($"Invalid response code in Step 1. StatusCode: {response.StatusCode} authorize url: {authorizeUrl}."); } // Get the request querystring to extract the state property var query = QueryHelpers.ParseQuery(response.RequestMessage.RequestUri.Query); var state = query["state"].ToString(); // The spec doesn't say where to post the login details to // but it's at /usernamepassword/login var loginPage = loginSettings.Authority.GetLeftPart(System.UriPartial.Authority) + "/usernamepassword/login"; _log(" - Login Step 2: Post login details to login page: " + loginPage); // Create a json post to that url with the riight properties var requestMessage = new HttpRequestMessage(HttpMethod.Post, loginPage) { Content = new StringContent(JsonConvert.SerializeObject(new { client_id = clientId, redirect_uri = loginSettings.RedirectUri.ToString(), tenant = loginSettings.Auth0Tenant, connection = loginSettings.Connection, username = loginSettings.UserName, state = state, password = loginSettings.Password, }), Encoding.UTF8, "application/json") }; response = await httpClient.SendAsync(requestMessage); if (response.StatusCode != HttpStatusCode.OK) { throw new InvalidOperationException($"Invalid response code in Step 2. StatusCode: {response.StatusCode} login page: {loginPage}. {await response.Content.ReadAsStringAsync()}"); } var doc = new HtmlDocument(); doc.LoadHtml(await response.Content.ReadAsStringAsync()); var form = doc.DocumentNode.FirstChild; var action = form.Attributes["action"].Value; _log($" - Login Step 3: The response contains a form. Post it to: {action}"); var inputElements = form .SelectNodes("input") .Select(x => new KeyValuePair <string, string> ( x.Attributes["name"].Value, HttpUtility.HtmlDecode(x.Attributes["value"].Value) ) ); requestMessage = new HttpRequestMessage(HttpMethod.Post, action) { Content = new FormUrlEncodedContent(inputElements) }; response = await httpClient.SendAsync(requestMessage); if (response.StatusCode != HttpStatusCode.OK) { throw new InvalidOperationException($"Invalid response code in Step 3. StatusCode: {response.StatusCode} action: {action}. {await response.Content.ReadAsStringAsync()}"); } var location = response.RequestMessage.RequestUri; _log($" - Login Step 4: We are now redirected at the redirect-page. Get the authorization code from url: {location}"); query = QueryHelpers.ParseQuery(location.Query); if (!query.TryGetValue("code", out var code)) { throw new InvalidOperationException("Failed step 4. Could not find code in url: " + location); } _log($" - Login Step 5: Swap authorization code for an access token. "); var tokenResponse = await httpClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest { Address = disco.TokenEndpoint, ClientId = clientId, ClientCredentialStyle = ClientCredentialStyle.AuthorizationHeader, ClientSecret = loginSettings.ClientSecret, Code = code, RedirectUri = loginSettings.RedirectUri.ToString(), CodeVerifier = pkce.CodeVerifier, Parameters = new Dictionary <string, string>() }); if (tokenResponse.HttpStatusCode != HttpStatusCode.OK) { throw new InvalidOperationException($"Failed step 5. statuscode not ok: {tokenResponse.HttpStatusCode} {tokenResponse.ErrorDescription} {tokenResponse.Error}"); } return(tokenResponse); }