internal async Task <DeviceAuthorizationResponse> BeginLogin() { var client = _clientFactory.CreateClient(); var disco = await HttpClientDiscoveryExtensions.GetDiscoveryDocumentAsync(client, _authConfigurations.Value.StsServer); if (disco.IsError) { throw new ApplicationException($"Status code: {disco.IsError}, Error: {disco.Error}"); } var deviceAuthorizationRequest = new DeviceAuthorizationRequest { Address = disco.DeviceAuthorizationEndpoint, ClientId = "deviceFlowWebClient" }; deviceAuthorizationRequest.Scope = "email profile openid"; var response = await client.RequestDeviceAuthorizationAsync(deviceAuthorizationRequest); if (response.IsError) { throw new Exception(response.Error); } return(response); }
public async Task Http_request_should_have_correct_format() { var handler = new NetworkHandler(HttpStatusCode.NotFound, "not found"); var client = new HttpClient(handler); var request = new DeviceAuthorizationRequest { Address = Endpoint, ClientId = "client" }; request.Headers.Add("custom", "custom"); request.Properties.Add("custom", "custom"); var _ = await client.RequestDeviceAuthorizationAsync(request); var httpRequest = handler.Request; httpRequest.Method.Should().Be(HttpMethod.Post); httpRequest.RequestUri.Should().Be(new Uri(Endpoint)); var headers = httpRequest.Headers; headers.Count().Should().Be(3); headers.Should().Contain(h => h.Key == "custom" && h.Value.First() == "custom"); var properties = httpRequest.Properties; properties.Count.Should().Be(1); var prop = properties.First(); prop.Key.Should().Be("custom"); ((string)prop.Value).Should().Be("custom"); }
public async Task Repeating_a_request_should_succeed() { var document = File.ReadAllText(FileName.Create("success_device_authorization_response.json")); var handler = new NetworkHandler(document, HttpStatusCode.OK); var request = new DeviceAuthorizationRequest { Address = Endpoint, ClientId = "client" }; var client = new HttpClient(handler); var response = await client.RequestDeviceAuthorizationAsync(request); response.IsError.Should().BeFalse(); response.ErrorType.Should().Be(ResponseErrorType.None); response.HttpStatusCode.Should().Be(HttpStatusCode.OK); response.DeviceCode.Should().Be("GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8"); response.UserCode.Should().Be("WDJB-MJHT"); response.VerificationUri.Should().Be("https://www.example.com/device"); response.VerificationUriComplete.Should().Be("https://www.example.com/device?user_code=WDJB-MJHT"); response.ExpiresIn.Should().Be(1800); response.Interval.Should().Be(10); // repeat response = await client.RequestDeviceAuthorizationAsync(request); response.IsError.Should().BeFalse(); response.ErrorType.Should().Be(ResponseErrorType.None); response.HttpStatusCode.Should().Be(HttpStatusCode.OK); response.DeviceCode.Should().Be("GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8"); response.UserCode.Should().Be("WDJB-MJHT"); response.VerificationUri.Should().Be("https://www.example.com/device"); response.VerificationUriComplete.Should().Be("https://www.example.com/device?user_code=WDJB-MJHT"); response.ExpiresIn.Should().Be(1800); response.Interval.Should().Be(10); }
public async Task <DeviceAuthorizationResponse> GetDeviceCode() { var client = _clientFactory.CreateClient(); var disco = await GetDiscoveryEndpoints(client); var deviceAuthorizationRequest = new DeviceAuthorizationRequest { Address = disco.DeviceAuthorizationEndpoint, ClientId = _azureAdConfiguration.ClientId }; deviceAuthorizationRequest.Scope = "email profile openid"; var response = await client.RequestDeviceAuthorizationAsync(deviceAuthorizationRequest); if (response.IsError) { throw new Exception(response.Error); } return(response); }
private static async Task <DeviceAuthorizationResponse> RequestAuthorizationAsync() { var disco = await _cache.GetAsync(); if (disco.IsError) { throw new InvalidOperationException(disco.Error); } using (var httpClient = new HttpClient()) { using (var deviceAuthorizationRequest = new DeviceAuthorizationRequest { Address = disco.DeviceAuthorizationEndpoint, ClientId = "device" }) { var response = await httpClient.RequestDeviceAuthorizationAsync(deviceAuthorizationRequest); if (response.IsError) { throw new InvalidOperationException(response.Error); } WriteLine($"user code : {response.UserCode}"); WriteLine($"device code : {response.DeviceCode}"); WriteLine($"URL : {response.VerificationUri}"); WriteLine($"Complete URL: {response.VerificationUriComplete}"); WriteLine($"{Environment.NewLine}Press enter to launch browser ({response.VerificationUri})"); ReadLine(); Process.Start(new ProcessStartInfo(response.VerificationUriComplete) { UseShellExecute = true }); return(response); } } }
protected virtual async Task <TokenResponse> RequestDeviceAuthorizationAsync(HttpClient httpClient, IdentityClientConfiguration configuration) { var discoveryResponse = await GetDiscoveryResponse(configuration); var request = new DeviceAuthorizationRequest() { Address = discoveryResponse.DeviceAuthorizationEndpoint, Scope = configuration.Scope, ClientId = configuration.ClientId, ClientSecret = configuration.ClientSecret, }; IdentityModelHttpRequestMessageOptions.ConfigureHttpRequestMessage?.Invoke(request); await AddParametersToRequestAsync(configuration, request); var response = await httpClient.RequestDeviceAuthorizationAsync(request); if (response.IsError) { throw new AbpException(response.ErrorDescription); } Logger.LogInformation($"First copy your one-time code: {response.UserCode}"); Logger.LogInformation($"Open {response.VerificationUri} in your browser..."); for (var i = 0; i < ((response.ExpiresIn ?? 300) / response.Interval + 1); i++) { await Task.Delay(response.Interval * 1000); var tokenResponse = await httpClient.RequestDeviceTokenAsync(new DeviceTokenRequest { Address = discoveryResponse.TokenEndpoint, ClientId = configuration.ClientId, ClientSecret = configuration.ClientSecret, DeviceCode = response.DeviceCode }); if (tokenResponse.IsError) { switch (tokenResponse.Error) { case "slow_down": case "authorization_pending": break; case "expired_token": throw new AbpException("This 'device_code' has expired. (expired_token)"); case "access_denied": throw new AbpException("User denies the request(access_denied)"); } } if (!tokenResponse.IsError) { return(tokenResponse); } } throw new AbpException("Timeout!"); }
protected async override Task <int> ExecuteCommand(LoginCommand arguments) { Console.WriteLine("Logging in..."); logger.LogInformation("Logging in... with {Arguments}", arguments); if (!arguments.NoCache) { var userToken = await tokenStorage.LoadUserTokenAsync(); logger.LogInformation("Loaded {UserToken}", userToken); if (userToken != null) { userToken = await refreshTokenHandler.RefreshTokenAsync(userToken); logger.LogInformation("Refreshed {UserToken}", userToken); if (userToken != null) { Console.WriteLine("Login successful!"); logger.LogInformation("Login successful!"); await StoreToken(arguments, userToken); return(0); } } } var disco = await discoveryProvider.FetchDiscoveryDocument(); var request = new DeviceAuthorizationRequest { Address = disco.DeviceAuthorizationEndpoint, ClientId = configurationProvider.ClientId, Scope = configurationProvider.Scope }; logger.LogInformation("RequestDeviceAuthorizationAsync {Request}", request); var result = await httpClient.RequestDeviceAuthorizationAsync(request); if (result.IsError) { Console.WriteLine(result.Error); var ex = new Exception(result.Error); logger.LogError(ex, "RequestDeviceAuthorizationAsync {Request} {Response}", request, result); throw ex; } else { logger.LogInformation("RequestDeviceAuthorizationAsync {Request} {Response}", request, result); } Console.WriteLine($"Visit: {result.VerificationUri}"); Console.WriteLine(); Console.WriteLine("And enter this code"); Console.WriteLine("-------------------"); Console.WriteLine($"- {result.UserCode} -"); Console.WriteLine("-------------------"); var fetchToken = true; var interval = (result.Interval == 0 ? 5 : result.Interval) * 1000; var spinner = new ConsoleSpinner(); while (fetchToken) { spinner.Turn(); Console.Write(" Fetching token...."); var tokenResponse = await httpClient.RequestDeviceTokenAsync(new DeviceTokenRequest { Address = disco.TokenEndpoint, ClientId = configurationProvider.ClientId, DeviceCode = result.DeviceCode, }); if (tokenResponse.IsError) { if (tokenResponse.Error == "authorization_pending" || tokenResponse.Error == "slow_down") { await Task.Delay(interval); } else { spinner.ClearLine(); Console.WriteLine(tokenResponse.Error); throw new Exception(tokenResponse.Error); } } else { var userToken = new UserToken( tokenResponse.AccessToken, tokenResponse.RefreshToken, tokenResponse.IdentityToken, DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn) ); spinner.ClearLine(); Console.WriteLine("Login successful!"); await StoreToken(arguments, userToken); return(0); } } return(0); }
/// <summary> /// Sends a userinfo request. /// </summary> /// <param name="client">The client.</param> /// <param name="request">The request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns></returns> public static async Task <DeviceAuthorizationResponse> RequestDeviceAuthorizationAsync(this HttpMessageInvoker client, DeviceAuthorizationRequest request, CancellationToken cancellationToken = default) { var clone = request.Clone(); clone.Parameters.AddOptional(OidcConstants.AuthorizeRequest.Scope, request.Scope); clone.Method = HttpMethod.Post; clone.Prepare(); HttpResponseMessage response; try { response = await client.SendAsync(clone, cancellationToken).ConfigureAwait(); } catch (Exception ex) { return(ProtocolResponse.FromException <DeviceAuthorizationResponse>(ex)); } return(await ProtocolResponse.FromHttpResponseAsync <DeviceAuthorizationResponse>(response).ConfigureAwait()); }