Example #1
0
    /// <summary>
    /// Send a dynamic registration 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 <DynamicClientRegistrationResponse> RegisterClientAsync(this HttpMessageInvoker client, DynamicClientRegistrationRequest request, CancellationToken cancellationToken = default)
    {
        var clone = request.Clone();

        clone.Method  = HttpMethod.Post;
        clone.Content = new StringContent(JsonSerializer.Serialize(request.Document), Encoding.UTF8, "application/json");
        clone.Prepare();

        if (request.Token.IsPresent())
        {
            clone.SetBearerToken(request.Token);
        }

        HttpResponseMessage response;

        try
        {
            response = await client.SendAsync(clone, cancellationToken).ConfigureAwait();
        }
        catch (Exception ex)
        {
            return(ProtocolResponse.FromException <DynamicClientRegistrationResponse>(ex));
        }

        return(await ProtocolResponse.FromHttpResponseAsync <DynamicClientRegistrationResponse>(response).ConfigureAwait());
    }
Example #2
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 <UserInfoResponse> GetUserInfoAsync(this HttpMessageInvoker client, UserInfoRequest request, CancellationToken cancellationToken = default)
    {
        if (request.Token.IsMissing())
        {
            throw new ArgumentNullException(nameof(request.Token));
        }

        var clone = request.Clone();

        clone.Method = HttpMethod.Get;
        clone.SetBearerToken(request.Token);
        clone.Prepare();

        HttpResponseMessage response;

        try
        {
            response = await client.SendAsync(clone, cancellationToken).ConfigureAwait();
        }
        catch (Exception ex)
        {
            return(ProtocolResponse.FromException <UserInfoResponse>(ex));
        }

        return(await ProtocolResponse.FromHttpResponseAsync <UserInfoResponse>(response).ConfigureAwait());
    }
Example #3
0
    /// <summary>
    /// Sends a JSON web key set document 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 <JsonWebKeySetResponse> GetJsonWebKeySetAsync(this HttpMessageInvoker client, JsonWebKeySetRequest request, CancellationToken cancellationToken = default)
    {
        var clone = request.Clone();

        clone.Method = HttpMethod.Get;
        clone.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/jwk-set+json"));
        clone.Prepare();

        HttpResponseMessage response;

        try
        {
            response = await client.SendAsync(clone, cancellationToken).ConfigureAwait();

            string responseContent = null;
            if (response.Content != null)
            {
                responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait();
            }

            if (!response.IsSuccessStatusCode)
            {
                return(await ProtocolResponse.FromHttpResponseAsync <JsonWebKeySetResponse>(response, $"Error connecting to {clone.RequestUri.AbsoluteUri}: {response.ReasonPhrase}").ConfigureAwait());
            }
        }
        catch (Exception ex)
        {
            return(ProtocolResponse.FromException <JsonWebKeySetResponse>(ex, $"Error connecting to {clone.RequestUri.AbsoluteUri}. {ex.Message}."));
        }

        return(await ProtocolResponse.FromHttpResponseAsync <JsonWebKeySetResponse>(response).ConfigureAwait());
    }
Example #4
0
        /// <summary>
        /// Http请求
        /// </summary>
        /// <param name="client"></param>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task <ProtocolResponse <TV> > RequestAsync <TV, TK>(this HttpMessageInvoker client,
                                                                                TK request, CancellationToken cancellationToken = default)
            where TV : WeChatResponse
            where TK : WeChatRequest
        {
            request = request ?? throw new ArgumentNullException(nameof(request));
            client  = client ?? throw new ArgumentNullException(nameof(client));
            try
            {
                request.Prepare();
            }
            catch (Exception ex)
            {
                return(ProtocolResponse <TV> .FromException <ProtocolResponse <TV> >(ex, ResponseErrorType.Prepare));
            }


            HttpResponseMessage response;

            try
            {
                response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                return(ProtocolResponse <TV> .FromException <ProtocolResponse <TV> >(ex, ResponseErrorType.Exception));
            }

            return(await ProtocolResponse <TV> .FromHttpResponseAsync <ProtocolResponse <TV> >(response).ConfigureAwait(false));
        }
Example #5
0
        public async Task Empty_token_response_should_be_handled_correctly()
        {
            var emptyHttpResponse = new HttpResponseMessage();

            // It defaults to HttpStatusCode.OK
            emptyHttpResponse.IsSuccessStatusCode.Should().BeTrue();
            var tokenResponse = await ProtocolResponse.FromHttpResponseAsync <TokenResponse>(emptyHttpResponse);

            tokenResponse.IsError.Should().BeTrue();
            tokenResponse.ErrorType.Should().Be(ResponseErrorType.MissingContent);
            tokenResponse.Error.Should().Be("Missing Http content");
        }
Example #6
0
        public async Task Missing_token_should_return_error()
        {
            var data = new Dictionary <string, string>
            {
                { "client_id", client_id },
                { "client_secret", client_secret }
            };

            var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));

            response.StatusCode.Should().Be(HttpStatusCode.BadRequest);

            var result = await ProtocolResponse.FromHttpResponseAsync <TokenRevocationResponse>(response);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be("invalid_request");
        }
    /// <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());
    }
Example #8
0
    internal static async Task <TokenResponse> RequestTokenAsync(this HttpMessageInvoker client, ProtocolRequest request, CancellationToken cancellationToken = default)
    {
        request.Prepare();
        request.Method = HttpMethod.Post;

        HttpResponseMessage response;

        try
        {
            response = await client.SendAsync(request, cancellationToken).ConfigureAwait();
        }
        catch (Exception ex)
        {
            return(ProtocolResponse.FromException <TokenResponse>(ex));
        }

        return(await ProtocolResponse.FromHttpResponseAsync <TokenResponse>(response).ConfigureAwait());
    }
Example #9
0
        public static async Task <TokenResponse> RequestClientCredentialsTokenAsync(HttpMessageHandler handler,
                                                                                    X509Certificate2 certificate, string tokenEndpoint, CancellationToken cancellationToken)
        {
            var keyId = "SN=5E4299BE";

            var tokenEndpointUri = new Uri(tokenEndpoint);

            using var client = new HttpClient(handler);
            var httpRequest = new HttpRequestMessage(HttpMethod.Post, tokenEndpointUri);

            httpRequest.Headers.Accept.Clear();
            httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var contentParameters = new Dictionary <string, string>
            {
                { OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials },
            };

            var date = DateTime.UtcNow.ToString("R");

            httpRequest.Headers.Add("Date", date);
            httpRequest.Content = new FormUrlEncodedContent(contentParameters);
            var payload = await httpRequest.Content.ReadAsStringAsync();

            var digest = "SHA-256=" + Utils.Hash(payload);

            var signature = Utils.GetSignature(date, "post", tokenEndpointUri.PathAndQuery, digest, certificate);

            httpRequest.Headers.Add("Digest", digest);
            httpRequest.Headers.Add("authorization",
                                    $"Signature keyId=\"{keyId}\",algorithm=\"rsa-sha256\",headers=\"(request-target) date digest\",signature=\"{signature}\"");
            httpRequest.Headers.Add("TPP-Signature-Certificate",
                                    Convert.ToBase64String(certificate.Export(X509ContentType.Cert)));

            try
            {
                var response = await client.SendAsync(httpRequest, cancellationToken);

                return(await ProtocolResponse.FromHttpResponseAsync <TokenResponse>(response));
            }
            catch (Exception ex)
            {
                return(ProtocolResponse.FromException <TokenResponse>(ex));
            }
        }
Example #10
0
        protected async Task <TokenResponse> RequestAuthorizationUrlSignedAsync(string authorizationEndpoint, CancellationToken cancellationToken)
        {
            var httpRequest = new HttpRequestMessage(HttpMethod.Get, authorizationEndpoint);

            httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpRequest.Content = new StringContent(string.Empty);
            httpRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            try
            {
                var response = await Backchannel.SendAsync(httpRequest, cancellationToken);

                return(await ProtocolResponse.FromHttpResponseAsync <TokenResponse>(response));
            }
            catch (Exception ex)
            {
                return(ProtocolResponse.FromException <TokenResponse>(ex));
            }
        }
Example #11
0
        public async Task <TokenResponse> GetToken(string username, string pwd)
        {
            var client   = new HttpClient();
            var formData = new Dictionary <string, string>()
            {
                { "grant_type", "password" },
                { "client_id", _clientId },
                { "username", username },
                { "password", pwd },
            };
            var request = new HttpRequestMessage(HttpMethod.Post, $"{_authority}/connect/token")
            {
                Content = new FormUrlEncodedContent(formData)
            };
            var httpResponse = await client.SendAsync(request);

            var result = await ProtocolResponse.FromHttpResponseAsync <TokenResponse>(httpResponse);

            return(result);
        }
Example #12
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());
    }
Example #13
0
    /// <summary>
    /// Sends an OAuth token introspection 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 <TokenIntrospectionResponse> IntrospectTokenAsync(this HttpMessageInvoker client, TokenIntrospectionRequest request, CancellationToken cancellationToken = default)
    {
        var clone = request.Clone();

        clone.Method = HttpMethod.Post;
        clone.Parameters.AddRequired(OidcConstants.TokenIntrospectionRequest.Token, request.Token);
        clone.Parameters.AddOptional(OidcConstants.TokenIntrospectionRequest.TokenTypeHint, request.TokenTypeHint);
        clone.Prepare();

        HttpResponseMessage response;

        try
        {
            response = await client.SendAsync(clone, cancellationToken).ConfigureAwait();
        }
        catch (Exception ex)
        {
            return(ProtocolResponse.FromException <TokenIntrospectionResponse>(ex));
        }

        return(await ProtocolResponse.FromHttpResponseAsync <TokenIntrospectionResponse>(response).ConfigureAwait());
    }
Example #14
0
        public async Task Invalid_token_type_hint_should_return_error()
        {
            var tokens = await GetTokensAsync();

            (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();

            var data = new Dictionary <string, string>
            {
                { "client_id", client_id },
                { "client_secret", client_secret },
                { "token", tokens.AccessToken },
                { "token_type_hint", "not_valid" }
            };

            var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));

            response.StatusCode.Should().Be(HttpStatusCode.BadRequest);

            var result = await ProtocolResponse.FromHttpResponseAsync <TokenRevocationResponse>(response);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be("unsupported_token_type");
        }
Example #15
0
    /// <summary>
    /// Sends a discovery document 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 <DiscoveryDocumentResponse> GetDiscoveryDocumentAsync(this HttpMessageInvoker client, DiscoveryDocumentRequest request, CancellationToken cancellationToken = default)
    {
        string address;

        if (request.Address.IsPresent())
        {
            address = request.Address;
        }
        else if (client is HttpClient httpClient)
        {
            address = httpClient.BaseAddress.AbsoluteUri;
        }
        else
        {
            throw new ArgumentException("An address is required.");
        }

        var parsed    = DiscoveryEndpoint.ParseUrl(address, request.Policy.DiscoveryDocumentPath);
        var authority = parsed.Authority;
        var url       = parsed.Url;

        if (request.Policy.Authority.IsMissing())
        {
            request.Policy.Authority = authority;
        }

        var jwkUrl = "";

        if (!DiscoveryEndpoint.IsSecureScheme(new Uri(url), request.Policy))
        {
            return(ProtocolResponse.FromException <DiscoveryDocumentResponse>(new InvalidOperationException("HTTPS required"), $"Error connecting to {url}. HTTPS required."));
        }

        try
        {
            var clone = request.Clone();

            clone.Method = HttpMethod.Get;
            clone.Prepare();

            clone.RequestUri = new Uri(url);

            var response = await client.SendAsync(clone, cancellationToken).ConfigureAwait();

            string responseContent = null;

            if (response.Content != null)
            {
                responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait();
            }

            if (!response.IsSuccessStatusCode)
            {
                return(await ProtocolResponse.FromHttpResponseAsync <DiscoveryDocumentResponse>(response, $"Error connecting to {url}: {response.ReasonPhrase}").ConfigureAwait());
            }

            var disco = await ProtocolResponse.FromHttpResponseAsync <DiscoveryDocumentResponse>(response, request.Policy).ConfigureAwait();

            if (disco.IsError)
            {
                return(disco);
            }

            try
            {
                jwkUrl = disco.JwksUri;
                if (jwkUrl != null)
                {
                    var jwkClone = request.Clone <JsonWebKeySetRequest>();
                    jwkClone.Method  = HttpMethod.Get;
                    jwkClone.Address = jwkUrl;
                    jwkClone.Prepare();

                    var jwkResponse = await client.GetJsonWebKeySetAsync(jwkClone, cancellationToken).ConfigureAwait();

                    if (jwkResponse.IsError)
                    {
                        return(await ProtocolResponse.FromHttpResponseAsync <DiscoveryDocumentResponse>(jwkResponse.HttpResponse, $"Error connecting to {jwkUrl}: {jwkResponse.HttpErrorReason}").ConfigureAwait());
                    }

                    disco.KeySet = jwkResponse.KeySet;
                }

                return(disco);
            }
            catch (Exception ex)
            {
                return(ProtocolResponse.FromException <DiscoveryDocumentResponse>(ex, $"Error connecting to {jwkUrl}. {ex.Message}."));
            }
        }
        catch (Exception ex)
        {
            return(ProtocolResponse.FromException <DiscoveryDocumentResponse>(ex, $"Error connecting to {url}. {ex.Message}."));
        }
    }
Example #16
0
        private async Task <TokenResponse> GetToken(FormUrlEncodedContent body)
        {
            var response = await _client.PostAsync(TokenEndpoint, body);

            return(await ProtocolResponse.FromHttpResponseAsync <TokenResponse>(response));
        }