Beispiel #1
0
        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());
    }