Exemple #1
0
        public async Task StoreReferenceTokenAsync_should_persist_grant()
        {
            var token1 = new Token()
            {
                ClientId     = "client",
                Audience     = "aud",
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "foo")
                },
                Version = 1
            };

            await _referenceTokens.StoreReferenceTokenAsync("key", token1);

            var token2 = await _referenceTokens.GetReferenceTokenAsync("key");

            token1.ClientId.Should().Be(token2.ClientId);
            token1.Audience.Should().Be(token2.Audience);
            token1.CreationTime.Should().Be(token2.CreationTime);
            token1.Type.Should().Be(token2.Type);
            token1.Lifetime.Should().Be(token2.Lifetime);
            token1.Version.Should().Be(token2.Version);
        }
    public async Task StoreReferenceTokenAsync_should_persist_grant()
    {
        var token1 = new Token()
        {
            ClientId     = "client",
            Audiences    = { "aud" },
            CreationTime = DateTime.UtcNow,
            Lifetime     = 10,
            Type         = "type",
            Claims       = new List <Claim>
            {
                new Claim("sub", "123"),
                new Claim("scope", "foo")
            },
            Version = 1
        };

        var handle = await _referenceTokens.StoreReferenceTokenAsync(token1);

        var token2 = await _referenceTokens.GetReferenceTokenAsync(handle);

        token1.ClientId.Should().Be(token2.ClientId);
        token1.Audiences.Count.Should().Be(1);
        token1.Audiences.First().Should().Be("aud");
        token1.CreationTime.Should().Be(token2.CreationTime);
        token1.Type.Should().Be(token2.Type);
        token1.Lifetime.Should().Be(token2.Lifetime);
        token1.Version.Should().Be(token2.Version);
    }
Exemple #3
0
        public async Task RevokeRefreshToken(string clientId, string refreshToken)
        {
            var token = await _referenceTokenStore.GetReferenceTokenAsync(refreshToken);

            if (token.ClientId == clientId)
            {
                await _referenceTokenStore.RemoveReferenceTokenAsync(refreshToken);
            }
        }
Exemple #4
0
        private async Task <TokenValidationResult> ValidateReferenceAccessTokenAsync(string tokenHandle)
        {
            _log.TokenHandle = tokenHandle;
            var token = await _referenceTokenStore.GetReferenceTokenAsync(tokenHandle);

            if (token == null)
            {
                LogError("Token handle not found in token handle store.");
                return(Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken));
            }

            // TODO: review
            //if (token.Type != OidcConstants.TokenTypes.AccessToken)
            //{
            //    LogError("Token handle does not resolve to an access token - but instead to: " + token.Type);

            //    await _tokenHandles.RemoveAsync(tokenHandle);
            //    return Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken);
            //}

            if (DateTimeHelper.UtcNow >= token.CreationTime.AddSeconds(token.Lifetime))
            {
                LogError("Token expired.");

                await _referenceTokenStore.RemoveReferenceTokenAsync(tokenHandle);

                return(Invalid(OidcConstants.ProtectedResourceErrors.ExpiredToken));
            }

            // load the client that is defined in the token
            Client client = null;

            if (token.ClientId != null)
            {
                client = await _clients.FindEnabledClientByIdAsync(token.ClientId);
            }

            if (client == null)
            {
                LogError($"Client deleted or disabled: {token.ClientId}");
                return(Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken));
            }

            return(new TokenValidationResult
            {
                IsError = false,

                Client = client,
                Claims = ReferenceTokenToClaims(token),
                ReferenceToken = token,
                ReferenceTokenId = tokenHandle
            });
        }
Exemple #5
0
        /// <summary>
        /// Custom validation logic for access tokens.
        /// </summary>
        /// <param name="result">The validation result so far.</param>
        /// <returns>
        /// The validation result
        /// </returns>
        public async Task <TokenValidationResult> ValidateAccessTokenAsync(TokenValidationResult result)
        {
            if (!string.IsNullOrWhiteSpace(result.Jwt) && !result.IsError)
            {
                Token token = await Store.GetReferenceTokenAsync(result.Jwt);

                if (token == null)
                {
                    result.IsError = true;
                }
            }
            return(result);
        }
        /// <summary>
        /// Revoke access token only if it belongs to client doing the request.
        /// </summary>
        protected virtual async Task <bool> RevokeAccessTokenAsync(TokenRevocationRequestValidationResult validationResult)
        {
            try
            {
                var token = await ReferenceTokenStore.GetReferenceTokenAsync(validationResult.Token);

                string subject;
                if (token != null)
                {
                    subject = token.SubjectId;
                    if (token.ClientId == validationResult.Client.ClientId)
                    {
                        Logger.LogDebug("Access token revoked");
                        await ReferenceTokenStore.RemoveReferenceTokenAsync(validationResult.Token);
                    }
                    else
                    {
                        Logger.LogWarning("Client {clientId} tried to revoke an access token belonging to a different client: {clientId}", validationResult.Client.ClientId, token.ClientId);
                    }
                }
                else
                {
                    var validateAccessToken = await _tokenValidator.ValidateAccessTokenAsync(validationResult.Token);

                    if (validateAccessToken.IsError)
                    {
                        Logger.LogWarning("Client {clientId} access_token not valid: {clientId}", validationResult.Client.ClientId, token.ClientId);
                        return(false);
                    }
                    var queryClaims = from item in validateAccessToken.Claims
                                      where item.Type == JwtClaimTypes.Subject
                                      select item.Value;
                    subject = queryClaims.FirstOrDefault();
                }

                // now we need to revoke this subject
                var rts = RefreshTokenStore as IRefreshTokenStore2;
                await rts.RemoveRefreshTokensAsync(subject, validationResult.Client.ClientId);

                var clientExtra = validationResult.Client as ClientExtra;
                await _tokenRevocationEventHandler.TokenRevokedAsync(clientExtra, subject);

                return(true);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "unexpected error in revocation");
            }

            return(false);
        }
    private async Task <TokenValidationResult> ValidateReferenceAccessTokenAsync(string tokenHandle)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity("TokenValidator.ValidateReferenceAccessToken");

        _log.TokenHandle = tokenHandle;
        var token = await _referenceTokenStore.GetReferenceTokenAsync(tokenHandle);

        if (token == null)
        {
            LogError("Invalid reference token.");
            return(Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken));
        }

        if (token.CreationTime.HasExceeded(token.Lifetime, _clock.UtcNow.UtcDateTime))
        {
            LogError("Token expired.");

            await _referenceTokenStore.RemoveReferenceTokenAsync(tokenHandle);

            return(Invalid(OidcConstants.ProtectedResourceErrors.ExpiredToken));
        }

        // load the client that is defined in the token
        Client client = null;

        if (token.ClientId != null)
        {
            client = await _clients.FindEnabledClientByIdAsync(token.ClientId);
        }

        if (client == null)
        {
            LogError($"Client deleted or disabled: {token.ClientId}");
            return(Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken));
        }

        return(new TokenValidationResult
        {
            IsError = false,

            Client = client,
            Claims = ReferenceTokenToClaims(token),
            ReferenceToken = token,
            ReferenceTokenId = tokenHandle
        });
    }
Exemple #8
0
        private async Task <TokenValidationResult> ValidateReferenceAccessTokenAsync(string tokenHandle)
        {
            _log.TokenHandle = tokenHandle;
            var token = await _referenceTokenStore.GetReferenceTokenAsync(tokenHandle);

            if (token == null)
            {
                LogError("Token handle not found in token handle store.");
                return(Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken));
            }

            if (IdentityServerDateTime.UtcNow >= token.CreationTime.AddSeconds(token.Lifetime))
            {
                LogError("Token expired.");

                await _referenceTokenStore.RemoveReferenceTokenAsync(tokenHandle);

                return(Invalid(OidcConstants.ProtectedResourceErrors.ExpiredToken));
            }

            // load the client that is defined in the token
            Client client = null;

            if (token.ClientId != null)
            {
                client = await _clients.FindEnabledClientByIdAsync(token.ClientId);
            }

            if (client == null)
            {
                LogError($"Client deleted or disabled: {token.ClientId}");
                return(Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken));
            }

            return(new TokenValidationResult
            {
                IsError = false,

                Client = client,
                Claims = ReferenceTokenToClaims(token),
                ReferenceToken = token,
                ReferenceTokenId = tokenHandle
            });
        }
        /// <summary>
        /// Revoke access token only if it belongs to client doing the request.
        /// </summary>
        protected virtual async Task <bool> RevokeAccessTokenAsync(TokenRevocationRequestValidationResult validationResult)
        {
            var token = await ReferenceTokenStore.GetReferenceTokenAsync(validationResult.Token);

            if (token != null)
            {
                if (token.ClientId == validationResult.Client.ClientId)
                {
                    Logger.LogDebug("Access token revoked");
                    await ReferenceTokenStore.RemoveReferenceTokenAsync(validationResult.Token);
                }
                else
                {
                    Logger.LogWarning("Client {clientId} tried to revoke an access token belonging to a different client: {clientId}", validationResult.Client.ClientId, token.ClientId);
                }

                return(true);
            }

            return(false);
        }
        // revoke access token only if it belongs to client doing the request
        private async Task <bool> RevokeAccessTokenAsync(string handle, Client client)
        {
            var token = await _referenceTokenStore.GetReferenceTokenAsync(handle);

            if (token != null)
            {
                if (token.ClientId == client.ClientId)
                {
                    _logger.LogDebug("Access token revoked");
                    await _referenceTokenStore.RemoveReferenceTokenAsync(handle);
                }
                else
                {
                    _logger.LogWarning("Client {clientId} tried to revoke an access token belonging to a different client: {clientId}", client.ClientId, token.ClientId);
                }

                return(true);
            }

            return(false);
        }
        public async Task RemoveAllGrantsAsync_should_remove_all_grants()
        {
            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "123",
                Scopes    = new string[] { "foo1", "foo2" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client2",
                SubjectId = "123",
                Scopes    = new string[] { "foo3" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "456",
                Scopes    = new string[] { "foo3" }
            });

            var handle1 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar1"),
                    new Claim("scope", "bar2")
                }
            });

            var handle2 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client2",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar3")
                }
            });

            var handle3 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "456"),
                    new Claim("scope", "bar3")
                }
            });

            var handle4 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz1"),
                        new Claim("scope", "baz2")
                    }
                },
                Version = 1
            });

            var handle5 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "456"),
                        new Claim("scope", "baz3")
                    }
                },
                Version = 1
            });

            var handle6 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client2",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz3")
                    }
                },
                Version = 1
            });

            var handle7 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux1", "quux2" }
            });

            var handle8 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client2",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            var handle9 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = new IdentityServerUser("456").CreatePrincipal(),
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            await _subject.RemoveAllGrantsAsync("123", "client1");

            (await _referenceTokens.GetReferenceTokenAsync(handle1)).Should().BeNull();
            (await _referenceTokens.GetReferenceTokenAsync(handle2)).Should().NotBeNull();
            (await _referenceTokens.GetReferenceTokenAsync(handle3)).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle4)).Should().BeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle5)).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle6)).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync(handle7)).Should().BeNull();
            (await _codes.GetAuthorizationCodeAsync(handle8)).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync(handle9)).Should().NotBeNull();
        }
        public async Task RemoveAllGrantsAsync_should_remove_all_grants()
        {
            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "123",
                Scopes    = new string[] { "foo1", "foo2" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client2",
                SubjectId = "123",
                Scopes    = new string[] { "foo3" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "456",
                Scopes    = new string[] { "foo3" }
            });

            await _referenceTokens.StoreReferenceTokenAsync("key1", new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar1"),
                    new Claim("scope", "bar2"),
                },
            });

            await _referenceTokens.StoreReferenceTokenAsync("key2", new Token()
            {
                ClientId     = "client2",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar3"),
                },
            });

            await _referenceTokens.StoreReferenceTokenAsync("key3", new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "456"),
                    new Claim("scope", "bar3"),
                },
            });

            await _refreshTokens.StoreRefreshTokenAsync("key4", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz1"),
                        new Claim("scope", "baz2")
                    }
                },
                Version = 1
            });

            await _refreshTokens.StoreRefreshTokenAsync("key5", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "456"),
                        new Claim("scope", "baz3"),
                    }
                },
                Version = 1
            });

            await _refreshTokens.StoreRefreshTokenAsync("key6", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client2",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz3"),
                    }
                },
                Version = 1
            });

            await _codes.StoreAuthorizationCodeAsync("key7", new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux1", "quux2" }
            });

            await _codes.StoreAuthorizationCodeAsync("key8", new AuthorizationCode()
            {
                ClientId        = "client2",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            await _codes.StoreAuthorizationCodeAsync("key9", new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = IdentityServerPrincipal.Create("456", "alice"),
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            await _subject.RemoveAllGrantsAsync("123", "client1");

            (await _referenceTokens.GetReferenceTokenAsync("key1")).Should().BeNull();
            (await _referenceTokens.GetReferenceTokenAsync("key2")).Should().NotBeNull();
            (await _referenceTokens.GetReferenceTokenAsync("key3")).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync("key4")).Should().BeNull();
            (await _refreshTokens.GetRefreshTokenAsync("key5")).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync("key6")).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync("key7")).Should().BeNull();
            (await _codes.GetAuthorizationCodeAsync("key8")).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync("key9")).Should().NotBeNull();
        }