protected override async Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            string requestToken = null;

            string authorization = Request.Headers["Authorization"];

            if (string.IsNullOrEmpty(authorization))
            {
                return(null);
            }

            if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
            {
                requestToken = authorization.Substring("Bearer ".Length).Trim();
            }

            if (string.IsNullOrEmpty(requestToken))
            {
                return(null);
            }

            TokenValidator        tokenValidator = Context.Environment.ResolveDependency <TokenValidator>();
            TokenValidationResult result         = await tokenValidator.ValidateAccessTokenAsync(requestToken, Options.ExpectedScope);

            if (result.IsError)
            {
                return(null);
            }

            AuthenticationProperties properties = new AuthenticationProperties();
            ClaimsIdentity           identity   = new ClaimsIdentity(result.Claims, Options.AuthenticationType);

            return(new AuthenticationTicket(identity, properties));
        }
Beispiel #2
0
        internal async Task <IHttpActionResult> ProcessRequest(NameValueCollection parameters)
        {
            var token = parameters.Get("token");

            if (token.IsMissing())
            {
                var error = "token is missing";

                Logger.Error(error);
                await RaiseFailureEventAsync(error);

                return(BadRequest(_localizationService.GetMessage(MessageIds.MissingToken)));
            }

            var result = await _validator.ValidateAccessTokenAsync(token, parameters.Get("expectedScope"));

            if (result.IsError)
            {
                Logger.Info("Returning error: " + result.Error);
                await RaiseFailureEventAsync(result.Error);

                return(BadRequest(result.Error));
            }

            var response = result.Claims.ToClaimsDictionary();

            Logger.Info("End access token validation request");
            await RaiseSuccessEventAsync();

            return(Json(response));
        }
        public async Task <IHttpActionResult> Get()
        {
            Logger.Info("Start access token validation request");

            if (!_options.Endpoints.AccessTokenValidationEndpoint.IsEnabled)
            {
                Logger.Warn("Endpoint is disabled. Aborting");
                return(NotFound());
            }

            var parameters = Request.RequestUri.ParseQueryString();

            var token = parameters.Get("token");

            if (token.IsMissing())
            {
                Logger.Error("token is missing.");
                return(BadRequest(Messages.MissingToken));
            }

            var result = await _validator.ValidateAccessTokenAsync(token, parameters.Get("expectedScope"));

            if (result.IsError)
            {
                Logger.Info("Returning error: " + result.Error);
                return(BadRequest(result.Error));
            }

            var response = result.Claims.ToClaimsDictionary();

            Logger.Debug(JsonConvert.SerializeObject(response, Formatting.Indented));

            Logger.Info("Returning access token claims");
            return(Json(response));
        }
Beispiel #4
0
        public async Task <IHttpActionResult> GetUserInfo(HttpRequestMessage request)
        {
            Logger.Info("Start userinfo request");

            if (!_options.Endpoints.UserInfoEndpoint.IsEnabled)
            {
                Logger.Warn("Endpoint is disabled. Aborting");
                return(NotFound());
            }

            var tokenUsageResult = await _tokenUsageValidator.ValidateAsync(request);

            if (tokenUsageResult.TokenFound == false)
            {
                return(Error(Constants.ProtectedResourceErrors.InvalidToken));
            }

            var tokenResult = await _tokenValidator.ValidateAccessTokenAsync(
                tokenUsageResult.Token,
                Constants.StandardScopes.OpenId);

            if (tokenResult.IsError)
            {
                return(Error(tokenResult.Error));
            }

            // pass scopes/claims to profile service
            var subject = tokenResult.Claims.FirstOrDefault(c => c.Type == Constants.ClaimTypes.Subject).Value;
            var scopes  = tokenResult.Claims.Where(c => c.Type == Constants.ClaimTypes.Scope).Select(c => c.Value);

            var payload = await _generator.ProcessAsync(subject, scopes);

            return(new UserInfoResult(payload));
        }
Beispiel #5
0
        public async Task <CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            CustomGrantValidationResult grantResult = null;

            var param = request.Raw.Get("token");

            if (string.IsNullOrWhiteSpace(param))
            {
                grantResult = new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest);
            }

            var result = _validator.ValidateAccessTokenAsync(param).Result;

            if (result.IsError)
            {
                grantResult = new CustomGrantValidationResult(result.Error);
            }

            var subjectClaim = result.Claims.FirstOrDefault(x => x.Type == "sub");

            if (subjectClaim == null)
            {
                grantResult = new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest);
            }

            if (grantResult == null)
            {
                grantResult = new CustomGrantValidationResult(subjectClaim.Value, "access_token");
            }

            return(await Task.FromResult(grantResult));
        }
Beispiel #6
0
        public async Task <IHttpActionResult> GetUserInfo(HttpRequestMessage request)
        {
            Logger.Info("Start userinfo request");

            var tokenUsageResult = await _tokenUsageValidator.ValidateAsync(request.GetOwinContext());

            if (tokenUsageResult.TokenFound == false)
            {
                var error = "No token found.";

                Logger.Error(error);
                await RaiseFailureEventAsync(error);

                return(Error(Constants.ProtectedResourceErrors.InvalidToken));
            }

            Logger.Info("Token found: " + tokenUsageResult.UsageType.ToString());

            var tokenResult = await _tokenValidator.ValidateAccessTokenAsync(
                tokenUsageResult.Token,
                Constants.StandardScopes.OpenId);

            if (tokenResult.IsError)
            {
                Logger.Error(tokenResult.Error);
                await RaiseFailureEventAsync(tokenResult.Error);

                return(Error(tokenResult.Error));
            }

            // pass scopes/claims to profile service
            var tokenClaims = tokenResult.Claims;

            if (!tokenClaims.Any(x => x.Type == Constants.ClaimTypes.Subject))
            {
                var error = "Token contains no sub claim";
                Logger.Error(error);
                await RaiseFailureEventAsync(error);

                return(Error(Constants.ProtectedResourceErrors.InvalidToken));
            }


            var userClaims = tokenClaims.Where(x => !Constants.OidcProtocolClaimTypes.Contains(x.Type) ||
                                               Constants.AuthenticateResultClaimTypes.Contains(x.Type));
            var scopes = tokenResult.Claims.Where(c => c.Type == Constants.ClaimTypes.Scope).Select(c => c.Value);

            var payload = await _generator.ProcessAsync(userClaims, scopes, tokenResult.Client);

            Logger.Info("End userinfo request");
            await RaiseSuccessEventAsync();

            return(new UserInfoResult(payload));
        }
Beispiel #7
0
        public async Task <IHttpActionResult> Get()
        {
            Logger.Info("Start access token validation request");

            if (!_options.Endpoints.EnableAccessTokenValidationEndpoint)
            {
                var error = "Endpoint is disabled. Aborting";
                Logger.Warn(error);
                RaiseFailureEvent(error);

                return(NotFound());
            }

            var parameters = Request.RequestUri.ParseQueryString();

            var token = parameters.Get("token");

            if (token.IsMissing())
            {
                var error = "token is missing";

                Logger.Error(error);
                RaiseFailureEvent(error);
                return(BadRequest(_localizationService.GetMessage(MessageIds.MissingToken)));
            }

            var result = await _validator.ValidateAccessTokenAsync(token, parameters.Get("expectedScope"));

            if (result.IsError)
            {
                Logger.Info("Returning error: " + result.Error);
                RaiseFailureEvent(result.Error);

                return(BadRequest(result.Error));
            }

            var response = result.Claims.ToClaimsDictionary();

            Logger.Info("End access token validation request");
            RaiseSuccessEvent();

            return(Json(response));
        }
Beispiel #8
0
        Task <CustomGrantValidationResult> ICustomGrantValidator.ValidateAsync(ValidatedTokenRequest request)
        {
            CustomGrantValidationResult grantResult = null;

            var param = request.Raw.Get("token");

            if (string.IsNullOrWhiteSpace(param))
            {
                grantResult = new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest);
            }

            var result = _validator.ValidateAccessTokenAsync(param).Result;

            if (result.IsError)
            {
                grantResult = new CustomGrantValidationResult(result.Error);
            }

            var subjectClaim = result.Claims.FirstOrDefault(x => x.Type == "sub");

            if (subjectClaim == null)
            {
                grantResult = new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest);
            }

            if (grantResult == null)
            {
                var subject = subjectClaim.Value;

                grantResult = new CustomGrantValidationResult(subject, "access_token", new Claim[]
                {
                    new Claim(P5.IdentityServerCore.Constants.ClaimTypes.AccountGuid, Guid.NewGuid().ToString()),
                });
            }

            return(Task.FromResult(grantResult));
        }
Beispiel #9
0
        /// <summary>Validates the Custom grant request</summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task <CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            var userAccessToken    = request.Raw.Get("access_token");
            var clientRefererToken = request.Raw.Get("client_referer");

            if (string.IsNullOrWhiteSpace(userAccessToken))
            {
                return(new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest));
            }
            if (string.IsNullOrWhiteSpace(clientRefererToken))
            {
                return(new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest));
            }

            var result = await validator.ValidateAccessTokenAsync(userAccessToken).ConfigureAwait(false);

            if (result.IsError || result.Claims == null)
            {
                return(new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest));
            }

            var subjectClaim = result.Claims.FirstOrDefault(x => x.Type == Constants.ClaimTypes.Subject);

            if (subjectClaim == null)
            {
                return(new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest));
            }

            var client = result.Client;

            if (client == null || !client.RedirectUris.Any(x => x.IndexOf(clientRefererToken, StringComparison.OrdinalIgnoreCase) >= 0))
            {
                return(new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest));
            }

            return(new CustomGrantValidationResult(subjectClaim.Value, "access_token"));
        }
Beispiel #10
0
        public async Task Create_and_Validate_JWT_AccessToken_Valid()
        {
            var tokenService = new DefaultTokenService(
                null,
                _settings,
                null,
                null);

            var token = new Token(Constants.TokenTypes.AccessToken)
            {
                Audience = string.Format(Constants.AccessTokenAudience, _settings.IssuerUri),
                Issuer   = _settings.IssuerUri,
                Lifetime = 60,
                Client   = await _clients.FindClientByIdAsync("client")
            };

            var jwt = await tokenService.CreateSecurityTokenAsync(token);

            var validator = new TokenValidator(_settings, null, null, new DebugLogger());
            var result    = await validator.ValidateAccessTokenAsync(jwt);

            Assert.IsFalse(result.IsError);
            Assert.IsNotNull(result.Claims);
        }
        public async Task <IHttpActionResult> Get(HttpRequestMessage request)
        {
            Logger.Info("Start userinfo request");

            if (!_options.Endpoints.UserInfoEndpoint.IsEnabled)
            {
                Logger.Warn("Endpoint is disabled. Aborting");
                return(NotFound());
            }

            var authorizationHeader = request.Headers.Authorization;

            if (authorizationHeader == null ||
                !authorizationHeader.Scheme.Equals(Constants.TokenTypes.Bearer) ||
                authorizationHeader.Parameter.IsMissing())
            {
                return(Error(Constants.ProtectedResourceErrors.InvalidToken));
            }

            var result = await _tokenValidator.ValidateAccessTokenAsync(
                authorizationHeader.Parameter,
                Constants.StandardScopes.OpenId);

            if (result.IsError)
            {
                return(Error(result.Error));
            }

            // pass scopes/claims to profile service
            var subject = result.Claims.FirstOrDefault(c => c.Type == Constants.ClaimTypes.Subject).Value;
            var scopes  = result.Claims.Where(c => c.Type == Constants.ClaimTypes.Scope).Select(c => c.Value);

            var payload = await _generator.ProcessAsync(subject, scopes);

            return(new UserInfoResult(payload));
        }
Beispiel #12
0
        public override async Task <CompleteRegistrationRequestValidationResult> Validate(NameValueCollection parameters, string accessToken = null)
        {
            Logger.LogDebug($"[{nameof(CompleteRegistrationRequestValidator)}] Started trusted device registration request validation.");
            // The access token needs to be valid and have at least the openid scope.
            var tokenValidationResult = await TokenValidator.ValidateAccessTokenAsync(accessToken, IdentityServerConstants.StandardScopes.OpenId);

            if (tokenValidationResult.IsError)
            {
                return(Error(tokenValidationResult.Error, "Provided access token is not valid."));
            }
            // The access token must have at lease a 'sub' and 'client_id' claim.
            var claimsToValidate = new[] {
                JwtClaimTypes.Subject,
                JwtClaimTypes.ClientId
            };

            foreach (var claim in claimsToValidate)
            {
                var claimValue = tokenValidationResult.Claims.SingleOrDefault(x => x.Type == claim)?.Value;
                if (string.IsNullOrWhiteSpace(claimValue))
                {
                    return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken, $"Access token must contain the '{claim}' claim."));
                }
            }
            // Get 'code' parameter and retrieve it from the store.
            var code = parameters.Get(RegistrationRequestParameters.Code);

            if (string.IsNullOrWhiteSpace(code))
            {
                return(Error(OidcConstants.TokenErrors.InvalidGrant, $"Parameter '{nameof(RegistrationRequestParameters.Code)}' is not specified."));
            }
            var authorizationCode = await CodeChallengeStore.GetAuthorizationCode(code);

            if (authorizationCode == null)
            {
                return(Error(OidcConstants.TokenErrors.InvalidGrant, "Authorization code is invalid."));
            }
            // Validate that the consumer specified all required parameters.
            var parametersToValidate = new List <string> {
                RegistrationRequestParameters.CodeSignature,
                RegistrationRequestParameters.CodeVerifier,
                RegistrationRequestParameters.DeviceId,
                RegistrationRequestParameters.DevicePlatform
            };

            if (authorizationCode.InteractionMode == InteractionMode.Fingerprint)
            {
                parametersToValidate.Add(RegistrationRequestParameters.PublicKey);
            }
            if (authorizationCode.InteractionMode == InteractionMode.Pin)
            {
                parametersToValidate.Add(RegistrationRequestParameters.Pin);
            }
            var otpAuthenticatedValue = tokenValidationResult.Claims.FirstOrDefault(x => x.Type == BasicClaimTypes.OtpAuthenticated)?.Value;
            var otpAuthenticated      = !string.IsNullOrWhiteSpace(otpAuthenticatedValue) && bool.Parse(otpAuthenticatedValue);

            if (!otpAuthenticated)
            {
                parametersToValidate.Add(RegistrationRequestParameters.OtpCode);
            }
            foreach (var parameter in parametersToValidate)
            {
                var parameterValue = parameters.Get(parameter);
                if (string.IsNullOrWhiteSpace(parameterValue))
                {
                    return(Error(OidcConstants.TokenErrors.InvalidGrant, $"Parameter '{parameter}' is not specified."));
                }
            }
            var isValidPlatform = Enum.TryParse(typeof(DevicePlatform), parameters.Get(RegistrationRequestParameters.DevicePlatform), out var platform);

            if (!isValidPlatform)
            {
                return(Error(OidcConstants.TokenErrors.InvalidRequest, $"Parameter '{nameof(RegistrationRequestParameters.DevicePlatform)}' does not have a valid value."));
            }
            // Load client and validate that it allows the 'password' flow.
            var client = await LoadClient(tokenValidationResult);

            if (client == null)
            {
                return(Error(OidcConstants.AuthorizeErrors.UnauthorizedClient, $"Client is unknown or not enabled."));
            }
            if (client.AllowedGrantTypes.Except(Constants.RequiredGrantTypes).Any())
            {
                return(Error(OidcConstants.AuthorizeErrors.UnauthorizedClient, $"Client not authorized any of the following grant types: {string.Join(", ", Constants.RequiredGrantTypes)}"));
            }
            // Validate authorization code against code verifier given by the client.
            var codeVerifier = parameters.Get(RegistrationRequestParameters.CodeVerifier);
            var authorizationCodeValidationResult = await ValidateAuthorizationCode(code, authorizationCode, codeVerifier, parameters.Get(RegistrationRequestParameters.DeviceId), client);

            if (authorizationCodeValidationResult.IsError)
            {
                return(Error(authorizationCodeValidationResult.Error, authorizationCodeValidationResult.ErrorDescription));
            }
            // Validate given public key against signature for fingerprint.
            string publicKey = null;

            if (authorizationCode.InteractionMode == InteractionMode.Fingerprint)
            {
                publicKey = parameters.Get(RegistrationRequestParameters.PublicKey);
                var codeSignature             = parameters.Get(RegistrationRequestParameters.CodeSignature);
                var publicKeyValidationResult = ValidateSignature(publicKey, code, codeSignature);
                if (publicKeyValidationResult.IsError)
                {
                    return(Error(publicKeyValidationResult.Error, publicKeyValidationResult.ErrorDescription));
                }
            }
            // Find requested scopes.
            var requestedScopes = tokenValidationResult.Claims.Where(claim => claim.Type == JwtClaimTypes.Scope).Select(claim => claim.Value).ToList();
            // Create principal from incoming access token excluding protocol claims.
            var claims    = tokenValidationResult.Claims.Where(x => !Constants.ProtocolClaimsFilter.Contains(x.Type));
            var principal = Principal.Create("TrustedDevice", claims.ToArray());
            var userId    = tokenValidationResult.Claims.Single(x => x.Type == JwtClaimTypes.Subject).Value;

            // Validate OTP code, if needed.
            if (!otpAuthenticated)
            {
                var totpResult = await TotpService.Verify(
                    principal : principal,
                    code : parameters.Get(RegistrationRequestParameters.OtpCode),
                    purpose : Constants.TrustedDeviceOtpPurpose(userId, authorizationCode.DeviceId)
                    );

                if (!totpResult.Success)
                {
                    return(Error(totpResult.Error));
                }
            }
            // Finally return result.
            return(new CompleteRegistrationRequestValidationResult {
                IsError = false,
                Client = client,
                DeviceId = authorizationCode.DeviceId,
                DeviceName = parameters.Get(RegistrationRequestParameters.DeviceName),
                DevicePlatform = (DevicePlatform)platform,
                InteractionMode = authorizationCode.InteractionMode,
                Pin = parameters.Get(RegistrationRequestParameters.Pin),
                Principal = principal,
                PublicKey = publicKey,
                RequestedScopes = requestedScopes,
                UserId = userId
            });
        }
        public virtual async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var accessToken = context.Request.Raw["access_token"];

            if (accessToken.IsNullOrWhiteSpace())
            {
                context.Result = new GrantValidationResult
                {
                    IsError = true,
                    Error   = "invalid_access_token"
                };
                return;
            }

            var result = await TokenValidator.ValidateAccessTokenAsync(accessToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult
                {
                    IsError          = true,
                    Error            = result.Error,
                    ErrorDescription = result.ErrorDescription
                };
                return;
            }

            using (CurrentPrincipalAccessor.Change(result.Claims))
            {
                if (!Guid.TryParse(context.Request.Raw["LinkUserId"], out var linkUserId))
                {
                    context.Result = new GrantValidationResult
                    {
                        IsError = true,
                        Error   = "invalid_link_user_id"
                    };
                    return;
                }

                Guid?linkTenantId = null;
                if (!context.Request.Raw["LinkTenantId"].IsNullOrWhiteSpace())
                {
                    if (!Guid.TryParse(context.Request.Raw["LinkTenantId"], out var parsedGuid))
                    {
                        context.Result = new GrantValidationResult
                        {
                            IsError = true,
                            Error   = "invalid_link_tenant_id"
                        };
                        return;
                    }

                    linkTenantId = parsedGuid;
                }

                var isLinked = await IdentityLinkUserManager.IsLinkedAsync(
                    new IdentityLinkUserInfo(CurrentUser.GetId(), CurrentTenant.Id),
                    new IdentityLinkUserInfo(linkUserId, linkTenantId),
                    true);

                if (isLinked)
                {
                    using (CurrentTenant.Change(linkTenantId))
                    {
                        var user = await UserManager.GetByIdAsync(linkUserId);

                        var sub = await UserManager.GetUserIdAsync(user);

                        var additionalClaims = new List <Claim>();
                        await AddCustomClaimsAsync(additionalClaims, user, context);

                        context.Result = new GrantValidationResult(
                            sub,
                            GrantType,
                            additionalClaims.ToArray()
                            );
                    }
                }
                else
                {
                    context.Result = new GrantValidationResult
                    {
                        IsError = true,
                        Error   = Localizer["TheTargetUserIsNotLinkedToYou"]
                    };
                }
            }
        }
Beispiel #14
0
        public override async Task <InitRegistrationRequestValidationResult> Validate(NameValueCollection parameters, string accessToken = null)
        {
            Logger.LogDebug($"{nameof(InitRegistrationRequestValidator)}: Started trusted device registration request validation.");
            // The access token needs to be valid and have at least the openid scope.
            var tokenValidationResult = await TokenValidator.ValidateAccessTokenAsync(accessToken, IdentityServerConstants.StandardScopes.OpenId);

            if (tokenValidationResult.IsError)
            {
                return(Error(tokenValidationResult.Error, "Provided access token is not valid."));
            }
            // The access token must have a 'sub' and 'client_id' claim.
            var claimsToValidate = new[] {
                JwtClaimTypes.Subject,
                JwtClaimTypes.ClientId
            };

            foreach (var claim in claimsToValidate)
            {
                var claimValue = tokenValidationResult.Claims.SingleOrDefault(x => x.Type == claim)?.Value;
                if (string.IsNullOrWhiteSpace(claimValue))
                {
                    return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken, $"Access token must contain the '{claim}' claim."));
                }
            }
            // Validate that the consumer specified all required parameters.
            var parametersToValidate = new[] {
                RegistrationRequestParameters.CodeChallenge,
                RegistrationRequestParameters.DeviceId,
                RegistrationRequestParameters.Mode
            };

            foreach (var parameter in parametersToValidate)
            {
                var parameterValue = parameters.Get(parameter);
                if (string.IsNullOrWhiteSpace(parameterValue))
                {
                    return(Error(OidcConstants.TokenErrors.InvalidRequest, $"Parameter '{parameter}' is not specified."));
                }
            }
            var isValidInteraction = Enum.TryParse <InteractionMode>(parameters.Get(RegistrationRequestParameters.Mode), ignoreCase: true, out var mode);

            if (!isValidInteraction)
            {
                return(Error(OidcConstants.TokenErrors.InvalidRequest, $"Parameter '{RegistrationRequestParameters.Mode}' used for registration is not valid."));
            }
            var deliveryChannelParameter = parameters.Get(RegistrationRequestParameters.DeliveryChannel) ?? nameof(TotpDeliveryChannel.Sms);
            var isValidDeliveryChannel   = Enum.TryParse <TotpDeliveryChannel>(deliveryChannelParameter, ignoreCase: true, out var deliveryChannel);

            if (!isValidDeliveryChannel)
            {
                return(Error(OidcConstants.TokenErrors.InvalidRequest, $"Parameter '{RegistrationRequestParameters.DeliveryChannel}' is not valid."));
            }
            if (deliveryChannel is not TotpDeliveryChannel.Sms and not TotpDeliveryChannel.Viber)
            {
                return(Error(OidcConstants.TokenErrors.InvalidRequest, $"Allowed values for parameter '{RegistrationRequestParameters.DeliveryChannel}' are {nameof(TotpDeliveryChannel.Sms)} and {nameof(TotpDeliveryChannel.Viber)}."));
            }
            // Load client and validate that it allows the 'password' flow.
            var client = await LoadClient(tokenValidationResult);

            if (client == null)
            {
                return(Error(OidcConstants.AuthorizeErrors.UnauthorizedClient, "Client is unknown or not enabled."));
            }
            if (client.AllowedGrantTypes.Except(Constants.RequiredGrantTypes).Any())
            {
                return(Error(OidcConstants.AuthorizeErrors.UnauthorizedClient, $"Client not authorized any of the following grant types: {string.Join(", ", Constants.RequiredGrantTypes)}"));
            }
            // Find requested scopes.
            var requestedScopes = tokenValidationResult.Claims.Where(claim => claim.Type == JwtClaimTypes.Scope).Select(claim => claim.Value).ToList();
            // Create principal from incoming access token excluding protocol claims.
            var claims    = tokenValidationResult.Claims.Where(x => !Constants.ProtocolClaimsFilter.Contains(x.Type));
            var principal = Principal.Create("TrustedDevice", claims.ToArray());
            var userId    = tokenValidationResult.Claims.Single(x => x.Type == JwtClaimTypes.Subject).Value;

            // Finally return result.
            return(new InitRegistrationRequestValidationResult {
                IsError = false,
                Client = client,
                CodeChallenge = parameters.Get(RegistrationRequestParameters.CodeChallenge),
                DeviceId = parameters.Get(RegistrationRequestParameters.DeviceId),
                InteractionMode = mode,
                Principal = principal,
                RequestedScopes = requestedScopes,
                UserId = userId,
                DeliveryChannel = deliveryChannel
            });
        }