Esempio n. 1
0
        public async Task <IntrospectionResponse> IntrospectTokenAsync(TokenIntrospectionRequest request, CancellationToken cancellationToken = default)
        {
            var discovery = await _discoveryCache.GetAsync().ConfigureAwait(false);

            request.Address = discovery.IntrospectionEndpoint;
            return(await _httpClient.IntrospectTokenAsync(request, cancellationToken).ConfigureAwait(false));
        }
Esempio n. 2
0
    /// <summary>
    /// Introspects a token
    /// </summary>
    /// <param name="token"></param>
    /// <param name="tokenTypeHint"></param>
    /// <param name="parameters"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public Task <TokenIntrospectionResponse> Introspect(string token, string tokenTypeHint = null, Parameters parameters = null, CancellationToken cancellationToken = default)
    {
        var request = new TokenIntrospectionRequest
        {
            Token         = token,
            TokenTypeHint = tokenTypeHint
        };

        ApplyRequestParameters(request, parameters);

        return(_client().IntrospectTokenAsync(request, cancellationToken));
    }
Esempio n. 3
0
    /// <summary>
    /// Sets request parameters from the options.
    /// </summary>
    /// <param name="request">The request.</param>
    /// <param name="parameters">The parameters.</param>
    internal void ApplyRequestParameters(TokenIntrospectionRequest request, Parameters parameters)
    {
        request.Address                  = _options.Address;
        request.ClientId                 = _options.ClientId;
        request.ClientSecret             = _options.ClientSecret;
        request.ClientAssertion          = _options.ClientAssertion;
        request.ClientCredentialStyle    = _options.ClientCredentialStyle;
        request.AuthorizationHeaderStyle = _options.AuthorizationHeaderStyle;
        request.Parameters               = new Parameters(_options.Parameters);

        if (parameters != null)
        {
            foreach (var parameter in parameters)
            {
                request.Parameters.Add(parameter);
            }
        }
    }
Esempio n. 4
0
        public async Task <bool> ValidateToken(string token)
        {
            var request = new TokenIntrospectionRequest
            {
                Address      = $"{_options.Authority}/connect/introspect",
                ClientId     = _options.ApiName,
                ClientSecret = _options.ApiSecret,
                Token        = token
            };

            var response = await _client.IntrospectTokenAsync(request);

            if (response.IsError)
            {
                throw new Exception(response.Error);
            }

            // You might want to validate the scope here

            return(response.IsActive);
        }
        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 TokenIntrospectionRequest
            {
                Address = Endpoint,
                Token   = "token"
            };

            request.Headers.Add("custom", "custom");
            request.Properties.Add("custom", "custom");

            var response = await client.IntrospectTokenAsync(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(2);
            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");
        }
Esempio n. 6
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());
    }
        public async Task Repeating_a_request_should_succeed()
        {
            var document = File.ReadAllText(FileName.Create("success_introspection_response.json"));
            var handler  = new NetworkHandler(document, HttpStatusCode.OK);

            var client = new HttpClient(handler)
            {
                BaseAddress = new Uri(Endpoint)
            };

            var request = new TokenIntrospectionRequest
            {
                Token = "token"
            };

            var response = await client.IntrospectTokenAsync(request);

            response.IsError.Should().BeFalse();
            response.ErrorType.Should().Be(ResponseErrorType.None);
            response.HttpStatusCode.Should().Be(HttpStatusCode.OK);
            response.IsActive.Should().BeTrue();
            response.Claims.Should().NotBeEmpty();

            var audiences = response.Claims.Where(c => c.Type == "aud").ToList();

            audiences.Count().Should().Be(2);
            audiences.First().Value.Should().Be("https://idsvr4/resources");
            audiences.Skip(1).First().Value.Should().Be("api1");

            response.Claims.First(c => c.Type == "iss").Value.Should().Be("https://idsvr4");
            response.Claims.First(c => c.Type == "nbf").Value.Should().Be("1475824871");
            response.Claims.First(c => c.Type == "exp").Value.Should().Be("1475828471");
            response.Claims.First(c => c.Type == "client_id").Value.Should().Be("client");
            response.Claims.First(c => c.Type == "sub").Value.Should().Be("1");
            response.Claims.First(c => c.Type == "auth_time").Value.Should().Be("1475824871");
            response.Claims.First(c => c.Type == "idp").Value.Should().Be("local");
            response.Claims.First(c => c.Type == "amr").Value.Should().Be("password");
            response.Claims.First(c => c.Type == "active").Value.Should().Be("true");

            var scopes = response.Claims.Where(c => c.Type == "scope").ToList();

            scopes.Count().Should().Be(2);
            scopes.First().Value.Should().Be("api1");
            scopes.First().Issuer.Should().Be("https://idsvr4");
            scopes.Skip(1).First().Value.Should().Be("api2");
            scopes.Skip(1).First().Issuer.Should().Be("https://idsvr4");

            // repeat
            response = await client.IntrospectTokenAsync(request);

            response.IsError.Should().BeFalse();
            response.ErrorType.Should().Be(ResponseErrorType.None);
            response.HttpStatusCode.Should().Be(HttpStatusCode.OK);
            response.IsActive.Should().BeTrue();
            response.Claims.Should().NotBeEmpty();

            audiences = response.Claims.Where(c => c.Type == "aud").ToList();
            audiences.Count().Should().Be(2);
            audiences.First().Value.Should().Be("https://idsvr4/resources");
            audiences.Skip(1).First().Value.Should().Be("api1");

            response.Claims.First(c => c.Type == "iss").Value.Should().Be("https://idsvr4");
            response.Claims.First(c => c.Type == "nbf").Value.Should().Be("1475824871");
            response.Claims.First(c => c.Type == "exp").Value.Should().Be("1475828471");
            response.Claims.First(c => c.Type == "client_id").Value.Should().Be("client");
            response.Claims.First(c => c.Type == "sub").Value.Should().Be("1");
            response.Claims.First(c => c.Type == "auth_time").Value.Should().Be("1475824871");
            response.Claims.First(c => c.Type == "idp").Value.Should().Be("local");
            response.Claims.First(c => c.Type == "amr").Value.Should().Be("password");
            response.Claims.First(c => c.Type == "active").Value.Should().Be("true");

            scopes = response.Claims.Where(c => c.Type == "scope").ToList();
            scopes.Count().Should().Be(2);
            scopes.First().Value.Should().Be("api1");
            scopes.First().Issuer.Should().Be("https://idsvr4");
            scopes.Skip(1).First().Value.Should().Be("api2");
            scopes.Skip(1).First().Issuer.Should().Be("https://idsvr4");
        }
        public override async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
        {
            if (_options.EnableValidationResultCache)
            {
                var cachedClaims = await _options.ValidationResultCache.GetAsync(context.Token)
                                   .ConfigureAwait(false);

                if (cachedClaims != null)
                {
                    SetAuthenticationTicket(context, cachedClaims);
                    return;
                }
            }

            IntrospectionResponse response;

            try
            {
                var request = new TokenIntrospectionRequest
                {
                    Address = this.introspectionEndpoint,
                    Token   = context.Token
                };

                if (!string.IsNullOrEmpty(this._options.ClientId))
                {
                    request.ClientId     = this._options.ClientId;
                    request.ClientSecret = this._options.ClientSecret;
                }

                response = await this.httpClient.IntrospectTokenAsync(request)
                           .ConfigureAwait(false);

                if (response.IsError)
                {
                    _logger.WriteError("Error returned from introspection endpoint: " + response.Error);
                    return;
                }
                if (!response.IsActive)
                {
                    _logger.WriteVerbose("Inactive token: " + context.Token);
                    return;
                }
            }
            catch (Exception ex)
            {
                _logger.WriteError("Exception while contacting introspection endpoint: " + ex.ToString());
                return;
            }

            var claims = new List <Claim>();

            foreach (var claim in response.Claims)
            {
                if (!string.Equals(claim.Type, "active", StringComparison.Ordinal))
                {
                    claims.Add(new Claim(claim.Type, claim.Value));
                }
            }

            if (_options.EnableValidationResultCache)
            {
                await _options.ValidationResultCache.AddAsync(context.Token, claims)
                .ConfigureAwait(false);
            }

            SetAuthenticationTicket(context, claims);
        }