static async Task <BackchannelAuthenticationResponse> RequestBackchannelLoginAsync() { var disco = await _cache.GetAsync(); if (disco.IsError) { throw new Exception(disco.Error); } var cibaEp = disco.BackchannelAuthenticationEndpoint; var username = "******"; var bindingMessage = Guid.NewGuid().ToString("N").Substring(0, 10); var req = new BackchannelAuthenticationRequest() { Address = cibaEp, ClientId = "ciba", ClientSecret = "secret", Scope = "openid profile email resource1.scope1 offline_access", LoginHint = username, //IdTokenHint = "eyJhbGciOiJSUzI1NiIsImtpZCI6IkYyNjZCQzA3NTFBNjIyNDkzMzFDMzI4QUQ1RkIwMkJGIiwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo1MDAxIiwibmJmIjoxNjM4NDc3MDE2LCJpYXQiOjE2Mzg0NzcwMTYsImV4cCI6MTYzODQ3NzMxNiwiYXVkIjoiY2liYSIsImFtciI6WyJwd2QiXSwiYXRfaGFzaCI6ImE1angwelVQZ2twczBVS1J5VjBUWmciLCJzaWQiOiIzQTJDQTJDNjdBNTAwQ0I2REY1QzEyRUZDMzlCQTI2MiIsInN1YiI6IjgxODcyNyIsImF1dGhfdGltZSI6MTYzODQ3NzAwOCwiaWRwIjoibG9jYWwifQ.GAIHXYgEtXw5NasR0zPMW3jSKBuWujzwwnXJnfHdulKX-I3r47N0iqHm5v5V0xfLYdrmntjLgmdm0DSvdXswtZ1dh96DqS1zVm6yQ2V0zsA2u8uOt1RG8qtjd5z4Gb_wTvks4rbUiwi008FOZfRuqbMJJDSscy_YdEJqyQahdzkcUnWZwdbY8L2RUTxlAAWQxktpIbaFnxfr8PFQpyTcyQyw0b7xmYd9ogR7JyOff7IJIHPDur0wbRdpI1FDE_VVCgoze8GVAbVxXPtj4CtWHAv07MJxa9SdA_N-lBcrZ3PHTKQ5t1gFXwdQvp3togUJl33mJSru3lqfK36pn8y8ow", BindingMessage = bindingMessage, RequestedExpiry = 200 }; bool useRequestObject = false; if (useRequestObject) { req = new BackchannelAuthenticationRequest { Address = req.Address, ClientId = req.ClientId, ClientSecret = req.ClientSecret, RequestObject = CreateRequestObject(new Dictionary <string, string> { { OidcConstants.BackchannelAuthenticationRequest.Scope, req.Scope }, { OidcConstants.BackchannelAuthenticationRequest.LoginHint, req.LoginHint }, { OidcConstants.BackchannelAuthenticationRequest.IdTokenHint, req.IdTokenHint }, { OidcConstants.BackchannelAuthenticationRequest.BindingMessage, req.BindingMessage }, }), }; } var client = new HttpClient(); var response = await client.RequestBackchannelAuthenticationAsync(req); if (response.IsError) { throw new Exception(response.Error); } Console.WriteLine($"Login Hint : {username}"); Console.WriteLine($"Binding Message : {bindingMessage}"); Console.WriteLine($"Authentication Request Id : {response.AuthenticationRequestId}"); Console.WriteLine($"Expires In : {response.ExpiresIn}"); Console.WriteLine($"Interval : {response.Interval}"); Console.WriteLine(); Console.WriteLine($"\nPress enter to start polling the token endpoint."); Console.ReadLine(); 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 BackchannelAuthenticationRequest { Address = Endpoint, ClientId = "client", Scope = "scope", AcrValues = "acr_values", BindingMessage = "binding_message", ClientNotificationToken = "client_notification_token", UserCode = "user_code", RequestedExpiry = 1, IdTokenHint = "id_token_hint", LoginHintToken = "login_hint_token", LoginHint = "login_hint", Resource = { "resource1", "resource2" } }; request.Headers.Add("custom", "custom"); request.Properties.Add("custom", "custom"); var response = await client.RequestBackchannelAuthenticationAsync(request); var httpRequest = handler.Request; httpRequest.Method.Should().Be(HttpMethod.Post); httpRequest.RequestUri.Should().Be(new Uri(Endpoint)); httpRequest.Content.Should().NotBeNull(); 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"); var fields = QueryHelpers.ParseQuery(handler.Body); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.Scope, out var scope).Should().BeTrue(); scope.First().Should().Be("scope"); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.AcrValues, out var acr_values).Should().BeTrue(); acr_values.First().Should().Be("acr_values"); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.BindingMessage, out var binding_message).Should().BeTrue(); binding_message.First().Should().Be("binding_message"); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.ClientNotificationToken, out var client_notification_token).Should().BeTrue(); client_notification_token.First().Should().Be("client_notification_token"); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.UserCode, out var user_code).Should().BeTrue(); user_code.First().Should().Be("user_code"); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.RequestedExpiry, out var request_expiry).Should().BeTrue(); int.Parse(request_expiry.First()).Should().Be(1); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.IdTokenHint, out var id_token_hint).Should().BeTrue(); id_token_hint.First().Should().Be("id_token_hint"); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.LoginHintToken, out var login_hint_token).Should().BeTrue(); login_hint_token.First().Should().Be("login_hint_token"); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.LoginHint, out var login_hint).Should().BeTrue(); login_hint.First().Should().Be("login_hint"); fields.TryGetValue(OidcConstants.BackchannelAuthenticationRequest.Resource, out var resource).Should().BeTrue(); resource.Count.Should().Be(2); resource.First().Should().Be("resource1"); resource.Skip(1).First().Should().Be("resource2"); }
/// <summary> /// Sends a CIBA backchannel authentication 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 <BackchannelAuthenticationResponse> RequestBackchannelAuthenticationAsync(this HttpMessageInvoker client, BackchannelAuthenticationRequest request, CancellationToken cancellationToken = default) { var clone = request.Clone(); if (request.RequestObject.IsPresent()) { clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.Request, request.RequestObject); } else { clone.Parameters.AddRequired(OidcConstants.AuthorizeRequest.Scope, request.Scope); clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.ClientNotificationToken, request.ClientNotificationToken); clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.AcrValues, request.AcrValues); clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.LoginHintToken, request.LoginHintToken); clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.LoginHint, request.LoginHint); clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.IdTokenHint, request.IdTokenHint); clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.BindingMessage, request.BindingMessage); clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.UserCode, request.UserCode); if (request.RequestedExpiry.HasValue) { clone.Parameters.AddOptional(OidcConstants.BackchannelAuthenticationRequest.RequestedExpiry, request.RequestedExpiry.ToString()); } foreach (var resource in request.Resource) { clone.Parameters.AddRequired(OidcConstants.TokenRequest.Resource, resource, allowDuplicates: true); } } clone.Method = HttpMethod.Post; clone.Prepare(); HttpResponseMessage response; try { response = await client.SendAsync(clone, cancellationToken).ConfigureAwait(); } catch (Exception ex) { return(ProtocolResponse.FromException <BackchannelAuthenticationResponse>(ex)); } return(await ProtocolResponse.FromHttpResponseAsync <BackchannelAuthenticationResponse>(response).ConfigureAwait()); }