// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Tokens; using Moq; using Xunit; namespace Microsoft.AspNetCore.Identity.Service { public class TokenRequestFactoryTest { public static ProtocolErrorProvider ProtocolErrorProvider = new ProtocolErrorProvider(); [Fact] public async Task CreateTokenRequestAsyncFails_IfRequestDoesNotContainGrantType() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), Mock.Of(), Enumerable.Empty(), Mock.Of(), Mock.Of(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.MissingRequiredParameter(OpenIdConnectParameterNames.GrantType); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfGrantTypeIsNotSupported() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.GrantType] = new[] { "unsupported" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), Mock.Of(), Enumerable.Empty(), Mock.Of(), Mock.Of(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidGrantType("unsupported"); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfProvidedGrantIsNotValid() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "invalid" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(), Mock.Of(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidGrant(); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfGrantHasExpired() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetExpiredToken()), Mock.Of(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidLifetime(); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfClientIdIsMissing() { // Arrange var requestParameters = new Dictionary { }; var tokenRequestFactory = new TokenRequestFactory( Mock.Of(), Mock.Of(), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode()), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.MissingRequiredParameter(OpenIdConnectParameterNames.ClientId); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfClientIdDoesntMatchTheClientIdOnTheGrant() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "otherClientId" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode()), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidGrant(); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfClientIdIsNotValid() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: false), Mock.Of(), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode()), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidClientId("clientId"); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfClientCredentialsValidationFails() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: false), Mock.Of(), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode()), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidClientCredentials(); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfMultipleScopesArePresent() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.Scope] = new[] { "openid", "profile" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode()), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.TooManyParameters(OpenIdConnectParameterNames.Scope); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfRequestContainsInvalidScopes() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.Scope] = new[] { "invalid openid" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), GetScopeResolver(hasInvalidScopes: true), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode(), null, null, Enumerable.Empty(), new[] { "openid" }), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidScope("invalid"); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfRequestContains_ScopesNotPresentInTheAuthorizationRequest() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.Scope] = new[] { "invalid openid" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), GetScopeResolver(hasInvalidScopes: false), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode(), null, null, Enumerable.Empty(), new[] { "openid" }), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.UnauthorizedScope(); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfRedirectUriIsNotPresent() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), GetRedirectUriValidator(isRedirectUriValid: false), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode()), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.MissingRequiredParameter(OpenIdConnectParameterNames.RedirectUri); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfCodeVerifierIsMissing() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.RedirectUri] = new[] { "https://www.example.com" }, }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), GetRedirectUriValidator(isRedirectUriValid: true), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode(new[] { new Claim(IdentityServiceClaimTypes.CodeChallenge,"challenge"), new Claim(IdentityServiceClaimTypes.CodeChallengeMethod, ProofOfKeyForCodeExchangeChallengeMethods.SHA256), })), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.MissingRequiredParameter(ProofOfKeyForCodeExchangeParameterNames.CodeVerifier); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfCodeVerifier_HasMultipleValues() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.RedirectUri] = new[] { "https://www.example.com" }, [ProofOfKeyForCodeExchangeParameterNames.CodeVerifier] = new[] { "value1", "value2" }, }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), GetRedirectUriValidator(isRedirectUriValid: true), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode(new[] { new Claim(IdentityServiceClaimTypes.CodeChallenge,"challenge"), new Claim(IdentityServiceClaimTypes.CodeChallengeMethod, ProofOfKeyForCodeExchangeChallengeMethods.SHA256), })), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.TooManyParameters(ProofOfKeyForCodeExchangeParameterNames.CodeVerifier); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfCodeVerifierIsInvalid() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.RedirectUri] = new[] { "https://www.example.com" }, [ProofOfKeyForCodeExchangeParameterNames.CodeVerifier] = new[] { "@" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), GetRedirectUriValidator(isRedirectUriValid: true), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode(new[] { new Claim(IdentityServiceClaimTypes.CodeChallenge,"challenge"), new Claim(IdentityServiceClaimTypes.CodeChallengeMethod, ProofOfKeyForCodeExchangeChallengeMethods.SHA256), })), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidCodeVerifier(); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Theory] [InlineData("tooShort")] [InlineData("tooLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong")] public async Task CreateTokenRequestAsyncFails_IfTooShortOrTooLong(string verifier) { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.RedirectUri] = new[] { "https://www.example.com" }, [ProofOfKeyForCodeExchangeParameterNames.CodeVerifier] = new[] { verifier } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), GetRedirectUriValidator(isRedirectUriValid: true), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode(new[] { new Claim(IdentityServiceClaimTypes.CodeChallenge,"challenge"), new Claim(IdentityServiceClaimTypes.CodeChallengeMethod, ProofOfKeyForCodeExchangeChallengeMethods.SHA256), })), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidCodeVerifier(); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestAsyncFails_IfCodeVerifierDoesNotMatchChallenge() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.RedirectUri] = new[] { "https://www.example.com" }, [ProofOfKeyForCodeExchangeParameterNames.CodeVerifier] = new[] { "0123456789012345678901234567890123456789012" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), GetRedirectUriValidator(isRedirectUriValid: true), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode(new[] { new Claim(IdentityServiceClaimTypes.CodeChallenge,"challenge"), new Claim(IdentityServiceClaimTypes.CodeChallengeMethod, ProofOfKeyForCodeExchangeChallengeMethods.SHA256), })), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.InvalidCodeVerifier(); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } [Fact] public async Task CreateTokenRequestSucceeds_IfCodeVerifier_MatchesChallenge() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" }, [OpenIdConnectParameterNames.RedirectUri] = new[] { "https://www.example.com" }, [ProofOfKeyForCodeExchangeParameterNames.CodeVerifier] = new[] { "0123456789012345678901234567890123456789012" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), GetRedirectUriValidator(isRedirectUriValid: true), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode(new[] { new Claim(IdentityServiceClaimTypes.CodeChallenge,"_RpfHqw8pAZIomzVUE7sjRmHSM543WVdC4o-Kc4_3C0"), new Claim(IdentityServiceClaimTypes.CodeChallengeMethod, ProofOfKeyForCodeExchangeChallengeMethods.SHA256), })), new TimeStampManager(), new ProtocolErrorProvider()); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.True(tokenRequest.IsValid); } private IRedirectUriResolver GetRedirectUriValidator(bool isRedirectUriValid) { var mock = new Mock(); mock.Setup(m => m.ResolveRedirectUriAsync(It.IsAny(), It.IsAny())) .ReturnsAsync((string clientId, string redirectUri) => isRedirectUriValid ? RedirectUriResolutionResult.Valid(redirectUri) : RedirectUriResolutionResult.Invalid(ProtocolErrorProvider.MissingRequiredParameter(OpenIdConnectParameterNames.RedirectUri))); return mock.Object; } [Fact] public async Task CreateTokenRequestAsyncFails_IfRedirectUriDoesNotMatch() { // Arrange var requestParameters = new Dictionary { [OpenIdConnectParameterNames.GrantType] = new[] { "authorization_code" }, [OpenIdConnectParameterNames.Code] = new[] { "valid" }, [OpenIdConnectParameterNames.ClientId] = new[] { "clientId" } }; var tokenRequestFactory = new TokenRequestFactory( GetClientIdValidator(isClientIdValid: true, areClientCredentialsValid: true), Mock.Of(), Mock.Of(), Enumerable.Empty(), GetTestTokenManager(GetValidAuthorizationCode()), new TimeStampManager(), new ProtocolErrorProvider()); var expectedError = ProtocolErrorProvider.MissingRequiredParameter(OpenIdConnectParameterNames.RedirectUri); // Act var tokenRequest = await tokenRequestFactory.CreateTokenRequestAsync(requestParameters); // Assert Assert.NotNull(tokenRequest); Assert.False(tokenRequest.IsValid); Assert.Equal(expectedError, tokenRequest.Error, IdentityServiceErrorComparer.Instance); } private IClientIdValidator GetClientIdValidator(bool isClientIdValid = false, bool areClientCredentialsValid = false) { var clientIdValidator = new Mock(); clientIdValidator .Setup(cv => cv.ValidateClientIdAsync(It.IsAny())) .ReturnsAsync(isClientIdValid); clientIdValidator .Setup(cv => cv.ValidateClientCredentialsAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(areClientCredentialsValid); return clientIdValidator.Object; } private Token GetValidAuthorizationCode(IEnumerable additionalClaims = null) { var notBefore = EpochTime.GetIntDate(DateTime.UtcNow - TimeSpan.FromMinutes(20)).ToString(); var expires = EpochTime.GetIntDate(DateTime.UtcNow + TimeSpan.FromMinutes(10)).ToString(); var issuedAt = EpochTime.GetIntDate(DateTime.UtcNow).ToString(); return new AuthorizationCode(new Claim[] { new Claim(IdentityServiceClaimTypes.TokenUniqueId, Guid.NewGuid().ToString()), new Claim(IdentityServiceClaimTypes.NotBefore,notBefore), new Claim(IdentityServiceClaimTypes.Expires,expires), new Claim(IdentityServiceClaimTypes.IssuedAt,issuedAt), new Claim(IdentityServiceClaimTypes.UserId,"userId"), new Claim(IdentityServiceClaimTypes.ClientId,"clientId"), new Claim(IdentityServiceClaimTypes.RedirectUri, "https://www.example.com"), new Claim(IdentityServiceClaimTypes.Scope, "openid"), new Claim(IdentityServiceClaimTypes.GrantedToken, "id_token") } .Concat(additionalClaims ?? Enumerable.Empty())); } private ITokenManager GetTestTokenManager( Token token = null, string userId = null, string clientId = null, IEnumerable grantedTokens = null, IEnumerable grantedScopes = null) { userId = userId ?? "userId"; clientId = clientId ?? "clientId"; grantedTokens = grantedTokens ?? Enumerable.Empty(); var parsedScopes = grantedScopes?.Select(s => ApplicationScope.CanonicalScopes.TryGetValue(s, out var found) ? found : new ApplicationScope(clientId, s)) ?? new[] { ApplicationScope.OpenId, ApplicationScope.OfflineAccess }; var mock = new Mock(); if (token == null) { mock.Setup(m => m.ExchangeTokenAsync(It.IsAny())) .ReturnsAsync(AuthorizationGrant.Invalid(ProtocolErrorProvider.InvalidGrant())); } else { mock.Setup(m => m.ExchangeTokenAsync(It.IsAny())) .ReturnsAsync(AuthorizationGrant.Valid( userId, clientId, grantedTokens, parsedScopes, token)); } return mock.Object; } private Token GetExpiredToken() { var notBefore = EpochTime.GetIntDate(DateTime.UtcNow - TimeSpan.FromMinutes(20)).ToString(); var expires = EpochTime.GetIntDate(DateTime.UtcNow - TimeSpan.FromMinutes(10)).ToString(); return new TestToken(new Claim[] { new Claim(IdentityServiceClaimTypes.TokenUniqueId,Guid.NewGuid().ToString()), new Claim(IdentityServiceClaimTypes.IssuedAt,"946684800"), // 01/01/2000 new Claim(IdentityServiceClaimTypes.NotBefore,notBefore), new Claim(IdentityServiceClaimTypes.Expires,expires) }); } private IScopeResolver GetScopeResolver(bool hasInvalidScopes) { var mock = new Mock(); mock.Setup(m => m.ResolveScopesAsync(It.IsAny(), It.IsAny>())) .ReturnsAsync((string clientId, IEnumerable scopes) => !hasInvalidScopes ? ScopeResolutionResult.Valid(scopes.Select(s => CreateScope(s))) : ScopeResolutionResult.Invalid(ProtocolErrorProvider.InvalidScope(scopes.First()))); return mock.Object; ApplicationScope CreateScope(string s) => ApplicationScope.CanonicalScopes.TryGetValue(s, out var parsedScope) ? parsedScope : new ApplicationScope("resourceId", s); } private class TestToken : Token { public TestToken(IEnumerable claims) : base(claims) { } public override string Kind => "Test"; } } }