private async Task <AuthorizeRequestValidationResult> ValidateRequestObjectAsync(ValidatedAuthorizeRequest request)
        {
            //////////////////////////////////////////////////////////
            // validate request object
            /////////////////////////////////////////////////////////
            if (request.RequestObject.IsPresent())
            {
                // validate the request JWT for this client
                var jwtRequestValidationResult = await _jwtRequestValidator.ValidateAsync(request.Client, request.RequestObject);

                if (jwtRequestValidationResult.IsError)
                {
                    LogError("request JWT validation failure", request);
                    return(Invalid(request, description: "Invalid JWT request"));
                }

                // validate response_type match
                var responseType = request.Raw.Get(OidcConstants.AuthorizeRequest.ResponseType);
                if (responseType != null)
                {
                    if (jwtRequestValidationResult.Payload.TryGetValue(OidcConstants.AuthorizeRequest.ResponseType, out var payloadResponseType))
                    {
                        if (payloadResponseType != responseType)
                        {
                            LogError("response_type in JWT payload does not match response_type in request", request);
                            return(Invalid(request, description: "Invalid JWT request"));
                        }
                    }
                }

                if (jwtRequestValidationResult.Payload.TryGetValue(OidcConstants.AuthorizeRequest.ClientId, out var payloadClientId))
                {
                    var queryClientId = request.Raw.Get(OidcConstants.AuthorizeRequest.ClientId);
                    if (queryClientId.IsPresent() && !string.Equals(queryClientId, payloadClientId, StringComparison.Ordinal))
                    {
                        LogError("client_id in JWT payload does not match client_id in request", request);
                        return(Invalid(request, description: "Invalid JWT request"));
                    }
                }
                else
                {
                    LogError("client_id is missing in JWT payload", request);
                    return(Invalid(request, description: "Invalid JWT request"));
                }

                // merge jwt payload values into original request parameters
                foreach (var key in jwtRequestValidationResult.Payload.Keys)
                {
                    var value = jwtRequestValidationResult.Payload[key];
                    request.Raw.Set(key, value);
                }

                request.RequestObjectValues = jwtRequestValidationResult.Payload;
            }

            return(Valid(request));
        }
Beispiel #2
0
        private async Task <AuthorizeRequestValidationResult> ReadJwtRequestAsync(ValidatedAuthorizeRequest request)
        {
            //////////////////////////////////////////////////////////
            // look for optional request params
            /////////////////////////////////////////////////////////
            var jwtRequest = request.Raw.Get(OidcConstants.AuthorizeRequest.Request);

            if (_options.Endpoints.EnableJwtRequestUri)
            {
                var jwtRequestUri = request.Raw.Get(OidcConstants.AuthorizeRequest.RequestUri);
                if (jwtRequest.IsPresent() && jwtRequestUri.IsPresent())
                {
                    LogError("Both request and request_uri are present", request);
                    return(Invalid(request, description: "Only one request parameter is allowed"));
                }

                if (jwtRequestUri.IsPresent())
                {
                    // 512 is from the spec
                    if (jwtRequestUri.Length > 512)
                    {
                        LogError("request_uri is too long", request);
                        return(Invalid(request, description: "request_uri is too long"));
                    }

                    var jwt = await _jwtRequestUriHttpClient.GetJwtAsync(jwtRequestUri, request.Client);

                    if (jwt.IsMissing())
                    {
                        LogError("no value returned from request_uri", request);
                        return(Invalid(request, description: "no value returned from request_uri"));
                    }

                    jwtRequest = jwt;
                }
            }

            //////////////////////////////////////////////////////////
            // validate request JWT
            /////////////////////////////////////////////////////////
            if (jwtRequest.IsPresent())
            {
                // check length restrictions
                if (jwtRequest.Length >= _options.InputLengthRestrictions.Jwt)
                {
                    LogError("request value is too long", request);
                    return(Invalid(request, description: "Invalid request value"));
                }

                // validate the request JWT for this client
                var jwtRequestValidationResult = await _jwtRequestValidator.ValidateAsync(request.Client, jwtRequest);

                if (jwtRequestValidationResult.IsError)
                {
                    LogError("request JWT validation failure", request);
                    return(Invalid(request, description: "Invalid JWT request"));
                }

                // validate client_id match
                if (jwtRequestValidationResult.Payload.TryGetValue(OidcConstants.AuthorizeRequest.ClientId, out var payloadClientId))
                {
                    if (payloadClientId != request.Client.ClientId)
                    {
                        LogError("client_id in JWT payload does not match client_id in request", request);
                        return(Invalid(request, description: "Invalid JWT request"));
                    }
                }

                // validate response_type match
                var responseType = request.Raw.Get(OidcConstants.AuthorizeRequest.ResponseType);
                if (responseType != null)
                {
                    if (jwtRequestValidationResult.Payload.TryGetValue(OidcConstants.AuthorizeRequest.ResponseType, out var payloadResponseType))
                    {
                        if (payloadResponseType != responseType)
                        {
                            LogError("response_type in JWT payload does not match response_type in request", request);
                            return(Invalid(request, description: "Invalid JWT request"));
                        }
                    }
                }

                // merge jwt payload values into original request parameters
                foreach (var key in jwtRequestValidationResult.Payload.Keys)
                {
                    var value = jwtRequestValidationResult.Payload[key];
                    request.Raw.Set(key, value);
                }

                request.RequestObjectValues = jwtRequestValidationResult.Payload;
            }

            return(Valid(request));
        }
        private async Task <AuthorizeRequestValidationResult> ValidateRequestObjectAsync(ValidatedAuthorizeRequest request)
        {
            //////////////////////////////////////////////////////////
            // validate request object
            /////////////////////////////////////////////////////////
            if (request.RequestObject.IsPresent())
            {
                // validate the request JWT for this client
                var jwtRequestValidationResult = await _jwtRequestValidator.ValidateAsync(request.Client, request.RequestObject);

                if (jwtRequestValidationResult.IsError)
                {
                    LogError("request JWT validation failure", request);
                    return(Invalid(request, error: OidcConstants.AuthorizeErrors.InvalidRequestObject, description: "Invalid JWT request"));
                }

                // validate response_type match
                var responseType = request.Raw.Get(OidcConstants.AuthorizeRequest.ResponseType);
                if (responseType != null)
                {
                    if (jwtRequestValidationResult.Payload.TryGetValue(OidcConstants.AuthorizeRequest.ResponseType, out var payloadResponseType))
                    {
                        if (payloadResponseType != responseType)
                        {
                            LogError("response_type in JWT payload does not match response_type in request", request);
                            return(Invalid(request, description: "Invalid JWT request"));
                        }
                    }
                }

                // validate client_id mismatch
                if (jwtRequestValidationResult.Payload.TryGetValue(OidcConstants.AuthorizeRequest.ClientId, out var payloadClientId))
                {
                    if (!string.Equals(request.Client.ClientId, payloadClientId, StringComparison.Ordinal))
                    {
                        LogError("client_id in JWT payload does not match client_id in request", request);
                        return(Invalid(request, description: "Invalid JWT request"));
                    }
                }
                else
                {
                    LogError("client_id is missing in JWT payload", request);
                    return(Invalid(request, error: OidcConstants.AuthorizeErrors.InvalidRequestObject, description: "Invalid JWT request"));
                }

                var ignoreKeys = new[]
                {
                    JwtClaimTypes.Issuer,
                    JwtClaimTypes.Audience
                };

                // merge jwt payload values into original request parameters
                foreach (var key in jwtRequestValidationResult.Payload.Keys)
                {
                    if (ignoreKeys.Contains(key))
                    {
                        continue;
                    }

                    var value = jwtRequestValidationResult.Payload[key];

                    var qsValue = request.Raw.Get(key);
                    if (qsValue != null)
                    {
                        if (!string.Equals(value, qsValue, StringComparison.Ordinal))
                        {
                            LogError("parameter mismatch between request object and query string parameter.", request);
                            return(Invalid(request, description: "Parameter mismatch in JWT request"));
                        }
                    }

                    request.Raw.Set(key, value);
                }

                request.RequestObjectValues = jwtRequestValidationResult.Payload;
            }

            return(Valid(request));
        }