예제 #1
0
        public async Task Refresh_token_should_be_retained_if_token_response_contains_only_access_token()
        {
            var document = File.ReadAllText(FileName.Create("success_access_token_response.json"));
            var handler  = new NetworkHandler(document, HttpStatusCode.OK);

            var tokenClient = new TokenClient(
                "http://server/token",
                "client",
                handler);

            var indirectOutputOfHttpResponses = new StubHttpResponsesHandler();
            var refreshHandler = new RefreshTokenDelegatingHandler(
                tokenClient,
                "refresh_token",
                "access_token",
                indirectOutputOfHttpResponses);

            var apiClient = new HttpClient(refreshHandler);

            await apiClient.GetStringAsync("http://someapi/somecall");

            refreshHandler.RefreshToken
            .Should()
            .Be("refresh_token", "Refresh token should be retained if token response contains only access token");
        }
예제 #2
0
        public async Task The_401_response_that_causes_token_refresh_and_retry_should_be_disposed_to_unblock_socket()
        {
            var document = File.ReadAllText(FileName.Create("success_token_response.json"));
            var handler  = new NetworkHandler(document, HttpStatusCode.OK);

            var tokenClient = new TokenClient(
                "http://server/token",
                "client",
                handler);

            var tokenResponse = await tokenClient.RequestClientCredentialsAsync();

            var indirectOutputOfHttpResponses = new StubHttpResponsesHandler();
            var refreshHandler = new RefreshTokenDelegatingHandler(
                tokenClient,
                tokenResponse.RefreshToken,
                tokenResponse.AccessToken,
                indirectOutputOfHttpResponses);

            var apiClient = new HttpClient(refreshHandler);

            await apiClient.GetStringAsync("http://someapi/somecall");

            indirectOutputOfHttpResponses.FirstAttempt401Response
            .Disposed
            .Should()
            .BeTrue("Unauthorized response should be disposed to avoid socket blocking");
        }
 public TestClient(RefreshTokenDelegatingHandler refreshTokenHandler)
 {
     _client = new HttpClient(refreshTokenHandler)
     {
         BaseAddress = new Uri("http://testing")
     };
 }
        public async Task Can_refresh_access_tokens_in_parallel()
        {
            var logicalThreadCount     = 10;
            var callsPerThread         = 10;
            var maxCallsPerAccessToken = 20;

            var tokens = new TestTokens(maxCallsPerAccessToken);

            var handlerUnderTest = new RefreshTokenDelegatingHandler(
                new TestableOidcTokenRefreshClient(tokens, 2.Milliseconds()),
                tokens.InitialAccessToken,
                tokens.InitialRefreshToken,
                new TestServer(tokens, 0.Milliseconds()));

            using (var client = new TestClient(handlerUnderTest))
            {
                async Task PerformPingRequests()
                {
                    for (var i = 0; i < callsPerThread; i++)
                    {
                        await client.SecuredPing();
                    }
                }

                var tasks = Enumerable.Range(0, logicalThreadCount).Select(i => PerformPingRequests());

                await Task.WhenAll(tasks);
            }

            tokens.Count.Should().BeGreaterOrEqualTo(logicalThreadCount * callsPerThread / maxCallsPerAccessToken);
        }
        public async Task Can_refresh_access_tokens_with_sliding_refresh_tokens()
        {
            const int maxCallsPerAccessToken = 2;

            var tokens = new TestTokens(maxCallsPerAccessToken, _writeLine);

            var handlerUnderTest = new RefreshTokenDelegatingHandler(
                new TestableOidcTokenRefreshClient(tokens, TimeSpan.Zero),
                tokens.InitialAccessToken,
                tokens.InitialRefreshToken,
                new TestServer(tokens, TimeSpan.Zero));

            using (var client = new TestClient(handlerUnderTest))
            {
                tokens.Count.Should().Be(1);
                await client.SecuredPing();

                tokens.Count.Should().Be(1);
                await client.SecuredPing();

                tokens.Count.Should().Be(1);
                await client.SecuredPing();

                tokens.Count.Should().Be(2);
            }
        }
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (!(InnerHandler is RefreshTokenDelegatingHandler))
            {
                var tokenResponse = await _tokenClient.RequestResourceOwnerPasswordAsync(_options.Username, _options.Password, _options.ClientScope, cancellationToken : cancellationToken);

                InnerHandler = new RefreshTokenDelegatingHandler(_tokenClient, tokenResponse.RefreshToken, tokenResponse.AccessToken, InnerHandler ?? new HttpClientHandler());
            }
            return(await base.SendAsync(request, cancellationToken));
        }