Esempio n. 1
0
        public async Task DeviceCode_Not_Yet_Authorized()
        {
            deviceCode.IsAuthorized = false;

            var client = await _clients.FindClientByIdAsync("device_flow");

            var service = Factory.CreateDeviceCodeService();

            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);

            var validator = Factory.CreateDeviceCodeValidator(service);

            var request = new ValidatedTokenRequest();

            request.SetClient(client);

            var context = new DeviceCodeValidationContext {
                DeviceCode = handle, Request = request
            };

            await validator.ValidateAsync(context);

            context.Result.IsError.Should().BeTrue();
            context.Result.Error.Should().Be(OidcConstants.TokenErrors.AuthorizationPending);
        }
        public async Task Expired_DeviceCode()
        {
            deviceCode.CreationTime = DateTime.UtcNow.AddDays(-10);
            deviceCode.Lifetime     = 300;

            var client = await _clients.FindClientByIdAsync("device_flow");

            var service = Factory.CreateDeviceCodeService();

            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);

            var validator = Factory.CreateDeviceCodeValidator(service);

            var request = new ValidatedTokenRequest();

            request.SetClient(client);

            var context = new DeviceCodeValidationContext {
                DeviceCode = handle, Request = request
            };

            await validator.ValidateAsync(context);

            context.Result.IsError.Should().BeTrue();
            context.Result.Error.Should().Be(OidcConstants.TokenErrors.ExpiredToken);
        }
Esempio n. 3
0
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            _logger.LogDebug("Start token request validation");

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var raw = context.Request.Raw;

            _validatedRequest = new ValidatedTokenRequest
            {
                Raw = raw ?? throw new ArgumentNullException(nameof(raw)),
                            Options = _options
            };
            var customTokenRequestValidationContext = new CustomTokenRequestValidationContext()
            {
                Result = new TokenRequestValidationResult(_validatedRequest)
            };
            await _arbitraryNoSubjectRequestValidator.ValidateAsync(customTokenRequestValidationContext);

            if (customTokenRequestValidationContext.Result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           customTokenRequestValidationContext.Result.Error);
                return;
            }
            var clientValidationResult = await _clientSecretValidator.ValidateAsync(_validatedRequest.Raw);

            if (clientValidationResult == null)
            {
                throw new ArgumentNullException(nameof(clientValidationResult));
            }

            _validatedRequest.SetClient(clientValidationResult.Client, clientValidationResult.Secret);

            /////////////////////////////////////////////
            // check grant type
            /////////////////////////////////////////////
            var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType);

            if (grantType.IsMissing())
            {
                LogError("Grant type is missing");
                context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);
                return;
            }
            if (grantType.Length > _options.InputLengthRestrictions.GrantType)
            {
                LogError("Grant type is too long");
                context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);
                return;
            }

            _validatedRequest.GrantType = grantType;
            context.Result = new GrantValidationResult();
        }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            _logger.LogDebug("Start token request validation");


            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var raw = context.Request.Raw;

            _validatedRequest = new ValidatedTokenRequest
            {
                Raw = raw ?? throw new ArgumentNullException(nameof(raw)),
                            Options = _options
            };
            var customTokenRequestValidationContext = new CustomTokenRequestValidationContext()
            {
                Result = new TokenRequestValidationResult(_validatedRequest)
            };
            await _arbitraryNoSubjectRequestValidator.ValidateAsync(customTokenRequestValidationContext);

            if (customTokenRequestValidationContext.Result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           customTokenRequestValidationContext.Result.Error);
                return;
            }
            var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext);

            if (!clientResult.IsError)
            {
                _validatedRequest.SetClient(clientResult.Client);
            }


            /////////////////////////////////////////////
            // check grant type
            /////////////////////////////////////////////
            var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType);

            _validatedRequest.GrantType = grantType;
            context.Result = new GrantValidationResult();
        }
Esempio n. 5
0
        public async Task DeviceCode_Missing()
        {
            var client = await _clients.FindClientByIdAsync("device_flow");

            var service = Factory.CreateDeviceCodeService();

            var validator = Factory.CreateDeviceCodeValidator(service);

            var request = new ValidatedTokenRequest();

            request.SetClient(client);

            var context = new DeviceCodeValidationContext {
                DeviceCode = null, Request = request
            };

            await validator.ValidateAsync(context);

            context.Result.IsError.Should().BeTrue();
            context.Result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);
        }
Esempio n. 6
0
        public async Task Valid_DeviceCode()
        {
            var client = await _clients.FindClientByIdAsync("device_flow");

            var service = Factory.CreateDeviceCodeService();

            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);

            var validator = Factory.CreateDeviceCodeValidator(service);

            var request = new ValidatedTokenRequest();

            request.SetClient(client);

            var context = new DeviceCodeValidationContext {
                DeviceCode = handle, Request = request
            };

            await validator.ValidateAsync(context);

            context.Result.IsError.Should().BeFalse();
        }
Esempio n. 7
0
        public async Task DeviceCode_From_Different_Client()
        {
            var badActor = await _clients.FindClientByIdAsync("codeclient");

            var service = Factory.CreateDeviceCodeService();

            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);

            var validator = Factory.CreateDeviceCodeValidator(service);

            var request = new ValidatedTokenRequest();

            request.SetClient(badActor);

            var context = new DeviceCodeValidationContext {
                DeviceCode = handle, Request = request
            };

            await validator.ValidateAsync(context);

            context.Result.IsError.Should().BeTrue();
            context.Result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);
        }
Esempio n. 8
0
        public async Task DeviceCode_Polling_Too_Fast()
        {
            var client = await _clients.FindClientByIdAsync("device_flow");

            var service = Factory.CreateDeviceCodeService();

            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);

            var validator = Factory.CreateDeviceCodeValidator(service, throttlingService: new TestDeviceFlowThrottlingService(true));

            var request = new ValidatedTokenRequest();

            request.SetClient(client);

            var context = new DeviceCodeValidationContext {
                DeviceCode = handle, Request = request
            };

            await validator.ValidateAsync(context);

            context.Result.IsError.Should().BeTrue();
            context.Result.Error.Should().Be(OidcConstants.TokenErrors.SlowDown);
        }
Esempio n. 9
0
        public async Task User_Disabled()
        {
            var client = await _clients.FindClientByIdAsync("device_flow");

            var service = Factory.CreateDeviceCodeService();

            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);

            var validator = Factory.CreateDeviceCodeValidator(service, new TestProfileService(false));

            var request = new ValidatedTokenRequest();

            request.SetClient(client);

            var context = new DeviceCodeValidationContext {
                DeviceCode = handle, Request = request
            };

            await validator.ValidateAsync(context);

            context.Result.IsError.Should().BeTrue();
            context.Result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);
        }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            _logger.LogDebug("Start token request validation");

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var raw = context.Request.Raw;

            _validatedRequest = new ValidatedTokenRequest
            {
                Raw = raw ?? throw new ArgumentNullException(nameof(raw)),
                            Options = _options
            };
            var customTokenRequestValidationContext = new CustomTokenRequestValidationContext()
            {
                Result = new TokenRequestValidationResult(_validatedRequest)
            };
            await _arbitraryOpenIdConnectIdentityTokenRequestValidator.ValidateAsync(customTokenRequestValidationContext);

            if (customTokenRequestValidationContext.Result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           customTokenRequestValidationContext.Result.Error);
                return;
            }
            var clientValidationResult = await _clientSecretValidator.ValidateAsync(_validatedRequest.Raw);

            if (clientValidationResult == null)
            {
                throw new ArgumentNullException(nameof(clientValidationResult));
            }

            _validatedRequest.SetClient(clientValidationResult.Client, clientValidationResult.Secret);

            /////////////////////////////////////////////
            // check grant type
            /////////////////////////////////////////////
            var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType);

            if (grantType.IsMissing())
            {
                LogError("Grant type is missing");
                context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);
                return;
            }
            if (grantType.Length > _options.InputLengthRestrictions.GrantType)
            {
                LogError("Grant type is too long");
                context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);
                return;
            }
            // optional stuff;
            var accessTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.AccessTokenLifetime);

            if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride))
            {
                var accessTokenLifetime = Int32.Parse(accessTokenLifetimeOverride);
                if (accessTokenLifetime > 0 && accessTokenLifetime < context.Request.AccessTokenLifetime)
                {
                    context.Request.AccessTokenLifetime = accessTokenLifetime;
                }
                else
                {
                    var errorDescription =
                        $"{Constants.AccessTokenLifetime} out of range.   Must be > 0 and less than configured AccessTokenLifetime.";
                    LogError(errorDescription);
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription);
                    return;
                }
            }

            var providerValidator = _providerValidatorManager.FetchProviderValidator(raw[Constants.Authority]);
            var idToken           = raw[Constants.IdToken];
            var principal         = await providerValidator.ValidateToken(idToken);

            var subjectId    = principal.GetClaimValue(ClaimTypes.NameIdentifier);
            var newPrincipal = principal.AddUpdateClaim(ClaimTypes.NameIdentifier, $"myCompany.{subjectId}");

            principal = newPrincipal;

            _validatedRequest.GrantType = grantType;
            var resource = await _resourceStore.GetAllResourcesAsync();

            // get user's identity

            _principalAugmenter.AugmentPrincipal(principal);
            var userClaimsFinal = new List <Claim>()
            {
                new Claim(Constants.ArbitraryClaims, raw[Constants.ArbitraryClaims])
            };

            userClaimsFinal.AddRange(principal.Claims);
            userClaimsFinal.Add(new Claim(ProfileServiceManager.Constants.ClaimKey, Constants.ArbitraryOpenIdConnectIdTokenProfileService));

            context.Result = new GrantValidationResult(principal.GetNamedIdentifier(), Constants.ArbitraryOIDCResourceOwner, userClaimsFinal);
        }
Esempio n. 11
0
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            _logger.LogDebug("Start token request validation");

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var contextClient = (context.Request.Client as ClientExtra).ShallowCopy();

            context.Request.Client = contextClient;
            var raw = context.Request.Raw;

            _validatedRequest = new ValidatedTokenRequest
            {
                Raw = raw ?? throw new ArgumentNullException(nameof(raw)),
                            Options = _options
            };
            var customTokenRequestValidationContext = new CustomTokenRequestValidationContext()
            {
                Result = new TokenRequestValidationResult(_validatedRequest)
            };
            await _arbitraryIdentityRequestValidator.ValidateAsync(customTokenRequestValidationContext);

            if (customTokenRequestValidationContext.Result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           customTokenRequestValidationContext.Result.Error);
                return;
            }
            // validate HTTP for clients
            if (HttpMethods.IsPost(_httpContextAccessor.HttpContext.Request.Method) && _httpContextAccessor.HttpContext.Request.HasFormContentType)
            {
                // validate client
                var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext);

                if (!clientResult.IsError)
                {
                    _validatedRequest.SetClient(clientResult.Client);
                }
            }

            /////////////////////////////////////////////
            // check grant type
            /////////////////////////////////////////////
            var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType);


            _validatedRequest.GrantType = grantType;
            var resource = await _resourceStore.GetAllResourcesAsync();

            var subject = "";


            if (string.IsNullOrWhiteSpace(subject))
            {
                subject = context.Request.Raw.Get("subject");
            }
            // get user's identity
            var claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, subject),
                new Claim("sub", subject),
                new Claim(JwtClaimTypes.IdentityProvider, _arbitraryIdentityExtensionGrantOptions.IdentityProvider)
            };

            var principal = new ClaimsPrincipal(new ClaimsIdentity(claims));

            _principalAugmenter.AugmentPrincipal(principal);
            var userClaimsFinal = new List <Claim>();


            // optional stuff;
            var accessTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.AccessTokenLifetime);

            if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride))
            {
                int  accessTokenLifetime = 0;
                bool error = true;
                if (Int32.TryParse(accessTokenLifetimeOverride, out accessTokenLifetime))
                {
                    if (accessTokenLifetime > 0 && accessTokenLifetime <= context.Request.AccessTokenLifetime)
                    {
                        context.Request.AccessTokenLifetime = accessTokenLifetime;
                        error = false;
                    }
                }

                if (error)
                {
                    var errorDescription =
                        $"{Constants.AccessTokenLifetime} out of range.   Must be > 0 and <= configured AccessTokenLifetime.";
                    LogError(errorDescription);
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription);
                    return;
                }
            }
            // optional stuff;
            var idTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.IdTokenLifetime);

            if (!string.IsNullOrWhiteSpace(idTokenLifetimeOverride))
            {
                int  idTokenLifetime = 0;
                bool error           = true;
                if (Int32.TryParse(idTokenLifetimeOverride, out idTokenLifetime))
                {
                    if (idTokenLifetime > 0 && idTokenLifetime <= context.Request.Client.IdentityTokenLifetime)
                    {
                        context.Request.Client.IdentityTokenLifetime = idTokenLifetime;
                        error = false;
                    }
                }

                if (error)
                {
                    var errorDescription =
                        $"{Constants.IdTokenLifetime} out of range.   Must be > 0 and <= configured IdentityTokenLifetime.";
                    LogError(errorDescription);
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription);
                    return;
                }
            }

            context.Result = new GrantValidationResult(
                principal.GetSubjectId(),
                ArbitraryIdentityExtensionGrant.Constants.ArbitraryIdentity,
                userClaimsFinal,
                _arbitraryIdentityExtensionGrantOptions.IdentityProvider);
        }
    /// <summary>
    /// Validates the request.
    /// </summary>
    /// <param name="parameters">The parameters.</param>
    /// <param name="clientValidationResult">The client validation result.</param>
    /// <returns></returns>
    /// <exception cref="System.ArgumentNullException">
    /// parameters
    /// or
    /// client
    /// </exception>
    public async Task <TokenRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, ClientSecretValidationResult clientValidationResult)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity("TokenRequestValidator.ValidateRequest");

        _logger.LogDebug("Start token request validation");

        _validatedRequest = new ValidatedTokenRequest
        {
            IssuerName                          = await _issuerNameService.GetCurrentAsync(),
            Raw                                 = parameters ?? throw new ArgumentNullException(nameof(parameters)),
                                        Options = _options
        };

        if (clientValidationResult == null)
        {
            throw new ArgumentNullException(nameof(clientValidationResult));
        }

        _validatedRequest.SetClient(clientValidationResult.Client, clientValidationResult.Secret, clientValidationResult.Confirmation);

        /////////////////////////////////////////////
        // check client protocol type
        /////////////////////////////////////////////
        if (_validatedRequest.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect)
        {
            LogError("Invalid protocol type for client",
                     new
            {
                clientId             = _validatedRequest.Client.ClientId,
                expectedProtocolType = IdentityServerConstants.ProtocolTypes.OpenIdConnect,
                actualProtocolType   = _validatedRequest.Client.ProtocolType
            });

            return(Invalid(OidcConstants.TokenErrors.InvalidClient));
        }

        /////////////////////////////////////////////
        // check grant type
        /////////////////////////////////////////////
        var grantType = parameters.Get(OidcConstants.TokenRequest.GrantType);

        if (grantType.IsMissing())
        {
            LogError("Grant type is missing");
            return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType));
        }

        if (grantType.Length > _options.InputLengthRestrictions.GrantType)
        {
            LogError("Grant type is too long");
            return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType));
        }

        _validatedRequest.GrantType = grantType;

        //////////////////////////////////////////////////////////
        // check for resource indicator and basic formatting
        //////////////////////////////////////////////////////////
        var resourceIndicators = parameters.GetValues(OidcConstants.TokenRequest.Resource) ?? Enumerable.Empty <string>();

        if (resourceIndicators?.Any(x => x.Length > _options.InputLengthRestrictions.ResourceIndicatorMaxLength) == true)
        {
            return(Invalid(OidcConstants.AuthorizeErrors.InvalidTarget, "Resource indicator maximum length exceeded"));
        }

        if (!resourceIndicators.AreValidResourceIndicatorFormat(_logger))
        {
            return(Invalid(OidcConstants.AuthorizeErrors.InvalidTarget, "Invalid resource indicator format"));
        }

        if (resourceIndicators.Count() > 1)
        {
            return(Invalid(OidcConstants.AuthorizeErrors.InvalidTarget, "Multiple resource indicators not supported on token endpoint."));
        }

        _validatedRequest.RequestedResourceIndicator = resourceIndicators.SingleOrDefault();


        //////////////////////////////////////////////////////////
        // run specific logic for grants
        //////////////////////////////////////////////////////////

        switch (grantType)
        {
        case OidcConstants.GrantTypes.AuthorizationCode:
            return(await RunValidationAsync(ValidateAuthorizationCodeRequestAsync, parameters));

        case OidcConstants.GrantTypes.ClientCredentials:
            return(await RunValidationAsync(ValidateClientCredentialsRequestAsync, parameters));

        case OidcConstants.GrantTypes.Password:
            return(await RunValidationAsync(ValidateResourceOwnerCredentialRequestAsync, parameters));

        case OidcConstants.GrantTypes.RefreshToken:
            return(await RunValidationAsync(ValidateRefreshTokenRequestAsync, parameters));

        case OidcConstants.GrantTypes.DeviceCode:
            return(await RunValidationAsync(ValidateDeviceCodeRequestAsync, parameters));

        case OidcConstants.GrantTypes.Ciba:
            return(await RunValidationAsync(ValidateCibaRequestRequestAsync, parameters));

        default:
            return(await RunValidationAsync(ValidateExtensionGrantRequestAsync, parameters));
        }
    }
Esempio n. 13
0
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            _logger.LogDebug("Start token request validation");

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var raw = context.Request.Raw;

            _validatedRequest = new ValidatedTokenRequest
            {
                Raw = raw ?? throw new ArgumentNullException(nameof(raw)),
                            Options = _options
            };
            var customTokenRequestValidationContext = new CustomTokenRequestValidationContext()
            {
                Result = new TokenRequestValidationResult(_validatedRequest)
            };
            await _arbitraryResourceOwnerRequestValidator.ValidateAsync(customTokenRequestValidationContext);

            if (customTokenRequestValidationContext.Result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           customTokenRequestValidationContext.Result.Error);
                return;
            }
            var clientValidationResult = await _clientSecretValidator.ValidateAsync(_validatedRequest.Raw);

            if (clientValidationResult == null)
            {
                throw new ArgumentNullException(nameof(clientValidationResult));
            }

            _validatedRequest.SetClient(clientValidationResult.Client, clientValidationResult.Secret);

            /////////////////////////////////////////////
            // check grant type
            /////////////////////////////////////////////
            var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType);

            if (grantType.IsMissing())
            {
                LogError("Grant type is missing");
                context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);
                return;
            }
            if (grantType.Length > _options.InputLengthRestrictions.GrantType)
            {
                LogError("Grant type is too long");
                context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);
                return;
            }

            _validatedRequest.GrantType = grantType;
            var resource = await _resourceStore.GetAllResourcesAsync();

            var   subject             = "";
            Claim originAuthTimeClaim = null;
            // if access_token exists, it wins.
            var accessToken = context.Request.Raw.Get("access_token");

            if (!string.IsNullOrWhiteSpace(accessToken))
            {
                var validateAccessToken = await _tokenValidator.ValidateAccessTokenAsync(accessToken);

                var queryClaims = from item in validateAccessToken.Claims
                                  where item.Type == JwtClaimTypes.Subject
                                  select item.Value;
                subject = queryClaims.FirstOrDefault();

                originAuthTimeClaim = (from item in validateAccessToken.Claims
                                       where item.Type == $"origin_{JwtClaimTypes.AuthenticationTime}"
                                       select item).FirstOrDefault();
                if (originAuthTimeClaim == null)
                {
                    var authTimeClaim = (from item in validateAccessToken.Claims
                                         where item.Type == JwtClaimTypes.AuthenticationTime
                                         select item).FirstOrDefault();
                    originAuthTimeClaim = new
                                          Claim($"origin_{JwtClaimTypes.AuthenticationTime}",
                                                authTimeClaim.Value);
                }
            }

            if (string.IsNullOrWhiteSpace(subject))
            {
                subject = context.Request.Raw.Get("subject");
            }
            // get user's identity
            var claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, subject),
                new Claim("sub", subject)
            };

            var principal = new ClaimsPrincipal(new ClaimsIdentity(claims));

            _principalAugmenter.AugmentPrincipal(principal);
            var userClaimsFinal = new List <Claim>()
            {
            };


            // optional stuff;
            var accessTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.AccessTokenLifetime);

            if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride))
            {
                var accessTokenLifetime = Int32.Parse(accessTokenLifetimeOverride);
                if (accessTokenLifetime > 0 && accessTokenLifetime < context.Request.AccessTokenLifetime)
                {
                    context.Request.AccessTokenLifetime = accessTokenLifetime;
                }
                else
                {
                    var errorDescription =
                        $"{Constants.AccessTokenLifetime} out of range.   Must be > 0 and less than configured AccessTokenLifetime.";
                    LogError(errorDescription);
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription);
                    return;
                }
            }

            //  userClaimsFinal.Add(new Claim(ProfileServiceManager.Constants.ClaimKey, Constants.ArbitraryResourceOwnerProfileService));
            if (originAuthTimeClaim != null)
            {
                userClaimsFinal.Add(originAuthTimeClaim);
            }
            context.Result = new GrantValidationResult(principal.GetSubjectId(), ArbitraryResourceOwnerExtensionGrant.Constants.ArbitraryResourceOwner, userClaimsFinal);
        }
        /// <summary>
        /// Validates the request.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <param name="clientValidationResult">The client validation result.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">
        /// parameters
        /// or
        /// client
        /// </exception>
        public async Task <TokenRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, ClientSecretValidationResult clientValidationResult)
        {
            _logger.LogDebug("Start token request validation");

            _validatedRequest = new ValidatedTokenRequest
            {
                Raw = parameters ?? throw new ArgumentNullException(nameof(parameters)),
                            Options = _options
            };

            if (clientValidationResult == null)
            {
                throw new ArgumentNullException(nameof(clientValidationResult));
            }

            _validatedRequest.SetClient(clientValidationResult.Client, clientValidationResult.Secret, clientValidationResult.Confirmation);

            /////////////////////////////////////////////
            // check client protocol type
            /////////////////////////////////////////////
            if (_validatedRequest.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect)
            {
                LogError("Invalid protocol type for client",
                         new
                {
                    clientId             = _validatedRequest.Client.ClientId,
                    expectedProtocolType = IdentityServerConstants.ProtocolTypes.OpenIdConnect,
                    actualProtocolType   = _validatedRequest.Client.ProtocolType
                });

                return(Invalid(OidcConstants.TokenErrors.InvalidClient));
            }

            /////////////////////////////////////////////
            // check grant type
            /////////////////////////////////////////////
            var grantType = parameters.Get(OidcConstants.TokenRequest.GrantType);

            if (grantType.IsMissing())
            {
                LogError("Grant type is missing");
                return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType));
            }

            if (grantType.Length > _options.InputLengthRestrictions.GrantType)
            {
                LogError("Grant type is too long");
                return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType));
            }

            _validatedRequest.GrantType = grantType;

            switch (grantType)
            {
            //case OidcConstants.GrantTypes.AuthorizationCode:
            //    return await RunValidationAsync(ValidateAuthorizationCodeRequestAsync, parameters);
            case OidcConstants.GrantTypes.ClientCredentials:
                return(await RunValidationAsync(ValidateClientCredentialsRequestAsync, parameters));

            case OidcConstants.GrantTypes.Password:
                return(await RunValidationAsync(ValidateResourceOwnerCredentialRequestAsync, parameters));

            case OidcConstants.GrantTypes.RefreshToken:
                return(await RunValidationAsync(ValidateRefreshTokenRequestAsync, parameters));

            case OidcConstants.GrantTypes.DeviceCode:
                return(await RunValidationAsync(ValidateDeviceCodeRequestAsync, parameters));

            default:
                return(await RunValidationAsync(ValidateExtensionGrantRequestAsync, parameters));
            }
        }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            _logger.LogDebug("Start token request validation");


            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var raw = context.Request.Raw;

            _validatedRequest = new ValidatedTokenRequest
            {
                Raw = raw ?? throw new ArgumentNullException(nameof(raw)),
                            Options = _options
            };
            var customTokenRequestValidationContext = new CustomTokenRequestValidationContext()
            {
                Result = new TokenRequestValidationResult(_validatedRequest)
            };
            await _arbitraryResourceOwnerRequestValidator.ValidateAsync(customTokenRequestValidationContext);

            if (customTokenRequestValidationContext.Result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           customTokenRequestValidationContext.Result.Error);
                return;
            }


            var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext);

            if (!clientResult.IsError)
            {
                _validatedRequest.SetClient(clientResult.Client);
            }

            /////////////////////////////////////////////
            // get the grant type
            // NOTE: The identityserver4 pipeline before us validated to obvious stuff
            /////////////////////////////////////////////
            var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType);

            _validatedRequest.GrantType = grantType;

            var subject = "";

            if (string.IsNullOrWhiteSpace(subject))
            {
                subject = context.Request.Raw.Get("subject");
            }

            // get user's identity
            var claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, subject),
                new Claim("sub", subject)
            };

            var principal = new ClaimsPrincipal(new ClaimsIdentity(claims));

            _principalAugmenter.AugmentPrincipal(principal);

            // optional stuff;
            var accessTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.AccessTokenLifetime);

            if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride))
            {
                int  accessTokenLifetime = 0;
                bool error = true;
                if (Int32.TryParse(accessTokenLifetimeOverride, out accessTokenLifetime))
                {
                    if (accessTokenLifetime > 0 && accessTokenLifetime <= context.Request.AccessTokenLifetime)
                    {
                        context.Request.AccessTokenLifetime = accessTokenLifetime;
                        error = false;
                    }
                }
                if (error)
                {
                    var errorDescription =
                        $"{Constants.AccessTokenLifetime} out of range.   Must be > 0 and <= configured AccessTokenLifetime.";
                    LogError(errorDescription);
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription);
                    return;
                }
            }

            context.Result = new GrantValidationResult(principal.GetSubjectId(),
                                                       ArbitraryResourceOwnerExtensionGrant.Constants.ArbitraryResourceOwner);
        }