Beispiel #1
0
            public void Totally_different_words()
            {
                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
                string x      = "blerg smoo";
                string y      = "token code";
                var    result = comparer.Equals(x, y);

                result.Should().BeFalse();
            }
Beispiel #2
0
            public void Same_length_different_count()
            {
                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
                string x      = "code id_token token";
                string y      = "tokenizer bleegerfi";
                var    result = comparer.Equals(x, y);

                result.Should().BeFalse();
            }
Beispiel #3
0
            public void code_id_token_token_combo2()
            {
                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
                string x      = "code id_token token";
                string y      = "token id_token code";
                var    result = comparer.Equals(x, y);

                result.Should().BeTrue();
            }
Beispiel #4
0
            public void code_id_token_token_missing_code_and_token()
            {
                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
                string x      = "code id_token token";
                string y      = "id_token";
                var    result = comparer.Equals(x, y);

                result.Should().BeFalse();
            }
 public void Right_null_other_not()
 {
     ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
     string x = "";
     string y = null;
     var result = comparer.Equals(x, y);
     var expected = (x == y);
     result.Should().Be(expected);
 }
Beispiel #6
0
            public void code_token_both_ways()
            {
                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
                string x      = "code token";
                string y      = "token code";
                var    result = comparer.Equals(x, y);

                result.Should().BeTrue();
            }
 public void id_token_token()
 {
     ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
     string x = "id_token";
     string y = "token";
     var result = comparer.Equals(x, y);
     var expected = (x == y);
     result.Should().Be(expected);
 }
 public void Both_null()
 {
     ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
     string x = null;
     string y = null;
     var result = comparer.Equals(x, y);
     var expected = (x == y);
     result.Should().Be(expected);
 }
Beispiel #9
0
            public void Both_null()
            {
                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
                string x        = null;
                string y        = null;
                var    result   = comparer.Equals(x, y);
                var    expected = (x == y);

                result.Should().Be(expected);
            }
Beispiel #10
0
            public void Right_null_other_not()
            {
                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
                string x        = "";
                string y        = null;
                var    result   = comparer.Equals(x, y);
                var    expected = (x == y);

                result.Should().Be(expected);
            }
Beispiel #11
0
            public void id_token_token()
            {
                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
                string x        = "id_token";
                string y        = "token";
                var    result   = comparer.Equals(x, y);
                var    expected = (x == y);

                result.Should().Be(expected);
            }
 public void code_id_token_token_missing_code_and_token()
 {
     ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
     string x = "code id_token token";
     string y = "id_token";
     var result = comparer.Equals(x, y);
     result.Should().BeFalse();
 }
        public async Task <AuthorizeRequestValidationResult> ValidateAsync(ValidatedAuthorizeRequest request)
        {
            var parameters = request.Raw;

            request.Nonce = parameters.Get(OidcConstants.AuthorizeRequest.Nonce);

            var state = parameters.Get(OidcConstants.AuthorizeRequest.State);

            if (state.IsPresent())
            {
                request.State = state;
            }

            //////////////////////////////////////////////////////////
            // redirect_uri must be present and supported
            //////////////////////////////////////////////////////////
            var redirectUri = parameters.Get(OidcConstants.AuthorizeRequest.RedirectUri);

            if (redirectUri.IsMissing())
            {
                _logger.LogError($"Missing {OidcConstants.AuthorizeRequest.RedirectUri}");
                return(Invalid(request, OidcConstants.AuthorizeErrors.InvalidRequestUri, $"Missing {OidcConstants.AuthorizeRequest.RedirectUri}"));
            }

            //////////////////////////////////////////////////////////
            // response_type must be present and supported
            //////////////////////////////////////////////////////////
            var responseType = parameters.Get(OidcConstants.AuthorizeRequest.ResponseType);

            if (responseType.IsMissing())
            {
                _logger.LogError($"Missing {OidcConstants.AuthorizeRequest.ResponseType}");
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, $"Missing {OidcConstants.AuthorizeRequest.ResponseType}"));
            }
            if (!SupportedResponseTypes.Contains(responseType, _responseTypeEqualityComparer))
            {
                _logger.LogError("Response type not supported", responseType);
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, "Response type not supported"));
            }
            request.ResponseType = SupportedResponseTypes.First(
                supportedResponseType => _responseTypeEqualityComparer.Equals(supportedResponseType, responseType));

            //////////////////////////////////////////////////////////
            // match response_type to grant type
            //////////////////////////////////////////////////////////
            request.GrantType = Constants.ResponseTypeToGrantTypeMapping[responseType];
            //////////////////////////////////////////////////////////
            // check if flow is allowed at authorize endpoint
            //////////////////////////////////////////////////////////
            if (!Constants.AllowedGrantTypesForAuthorizeEndpoint.Contains(request.GrantType))
            {
                LogError("Invalid grant type", request.GrantType, request);
                return(Invalid(request, description: "Invalid response_type"));
            }

            // set default response mode for flow; this is needed for any client error processing below
            request.ResponseMode = Constants.AllowedResponseModesForGrantType[request.GrantType].First();

            //////////////////////////////////////////////////////////
            // client_id must be present and supported
            //////////////////////////////////////////////////////////

            request.ClientId = parameters.Get(OidcConstants.AuthorizeRequest.ClientId);


            if (request.ClientId.IsMissing())
            {
                _logger.LogError($"Missing {OidcConstants.AuthorizeRequest.ClientId}");
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, $"Missing {OidcConstants.AuthorizeRequest.ClientId}"));
            }
            //////////////////////////////////////////////////////////
            // redirect_uri must be present, and a valid uri
            //////////////////////////////////////////////////////////
            request.RedirectUri = parameters.Get(OidcConstants.AuthorizeRequest.RedirectUri);

            if (request.RedirectUri.IsMissing())
            {
                _logger.LogError($"Missing {OidcConstants.AuthorizeRequest.RedirectUri}");
                return(Invalid(request, OidcConstants.AuthorizeRequest.RedirectUri, $"Missing {OidcConstants.AuthorizeRequest.RedirectUri}"));
            }

            var clientRecord = await _clientSecretStore.FetchClientRecordAsync(_options.Scheme, request.ClientId);

            if (clientRecord == null)
            {
                _logger.LogError($"Missing {OidcConstants.AuthorizeRequest.ClientId}");
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, $"Missing {OidcConstants.AuthorizeRequest.ClientId}"));
            }
            if (!clientRecord.RedirectUris.Contains(request.RedirectUri))
            {
                _logger.LogError($"Missing {OidcConstants.AuthorizeRequest.RedirectUri}");
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, $"Missing {OidcConstants.AuthorizeRequest.ClientId}"));
            }

            //////////////////////////////////////////////////////////
            // check response_mode parameter and set response_mode
            //////////////////////////////////////////////////////////

            // check if response_mode parameter is present and valid
            var responseMode = parameters.Get(OidcConstants.AuthorizeRequest.ResponseMode);

            if (responseMode.IsPresent())
            {
                if (Constants.SupportedResponseModes.Contains(responseMode))
                {
                    if (Constants.AllowedResponseModesForGrantType[request.GrantType].Contains(responseMode))
                    {
                        request.ResponseMode = responseMode;
                    }
                    else
                    {
                        LogError("Invalid response_mode for flow", responseMode, request);
                        return(Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, description: "Invalid response_mode"));
                    }
                }
                else
                {
                    LogError("Unsupported response_mode", responseMode, request);
                    return(Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, description: "Invalid response_mode"));
                }
            }
            //////////////////////////////////////////////////////////
            // check if PKCE is required and validate parameters
            //////////////////////////////////////////////////////////
            if (request.GrantType == GrantType.AuthorizationCode || request.GrantType == GrantType.Hybrid)
            {
                _logger.LogDebug("Checking for PKCE parameters");

                /////////////////////////////////////////////////////////////////////////////
                // validate code_challenge and code_challenge_method
                /////////////////////////////////////////////////////////////////////////////
                var proofKeyResult = ValidatePkceParameters(request);

                if (proofKeyResult.IsError)
                {
                    return(proofKeyResult);
                }
            }

            return(Valid(request));
        }
 public void id_token_token_both_ways()
 {
     ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
     string x = "id_token token";
     string y = "token id_token";
     var result = comparer.Equals(x, y);
     result.Should().BeTrue();
 }
 public void Same_length_different_count()
 {
     ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
     string x = "code id_token token";
     string y = "tokenizer bleegerfi";
     var result = comparer.Equals(x, y);
     result.Should().BeFalse();
 }
 public void Totally_different_words()
 {
     ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
     string x = "blerg smoo";
     string y = "token code";
     var result = comparer.Equals(x, y);
     result.Should().BeFalse();
 }
    private AuthorizeRequestValidationResult ValidateCoreParameters(ValidatedAuthorizeRequest request)
    {
        //////////////////////////////////////////////////////////
        // check state
        //////////////////////////////////////////////////////////
        var state = request.Raw.Get(OidcConstants.AuthorizeRequest.State);

        if (state.IsPresent())
        {
            request.State = state;
        }

        //////////////////////////////////////////////////////////
        // response_type must be present and supported
        //////////////////////////////////////////////////////////
        var responseType = request.Raw.Get(OidcConstants.AuthorizeRequest.ResponseType);

        if (responseType.IsMissing())
        {
            LogError("Missing response_type", request);
            return(Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, "Missing response_type"));
        }

        // The responseType may come in in an unconventional order.
        // Use an IEqualityComparer that doesn't care about the order of multiple values.
        // Per https://tools.ietf.org/html/rfc6749#section-3.1.1 -
        // 'Extension response types MAY contain a space-delimited (%x20) list of
        // values, where the order of values does not matter (e.g., response
        // type "a b" is the same as "b a").'
        // http://openid.net/specs/oauth-v2-multiple-response-types-1_0-03.html#terminology -
        // 'If a response type contains one of more space characters (%20), it is compared
        // as a space-delimited list of values in which the order of values does not matter.'
        if (!Constants.SupportedResponseTypes.Contains(responseType, _responseTypeEqualityComparer))
        {
            LogError("Response type not supported", responseType, request);
            return(Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, "Response type not supported"));
        }

        // Even though the responseType may have come in in an unconventional order,
        // we still need the request's ResponseType property to be set to the
        // conventional, supported response type.
        request.ResponseType = Constants.SupportedResponseTypes.First(
            supportedResponseType => _responseTypeEqualityComparer.Equals(supportedResponseType, responseType));

        //////////////////////////////////////////////////////////
        // match response_type to grant type
        //////////////////////////////////////////////////////////
        request.GrantType = Constants.ResponseTypeToGrantTypeMapping[request.ResponseType];

        // set default response mode for flow; this is needed for any client error processing below
        request.ResponseMode = Constants.AllowedResponseModesForGrantType[request.GrantType].First();

        //////////////////////////////////////////////////////////
        // check if flow is allowed at authorize endpoint
        //////////////////////////////////////////////////////////
        if (!Constants.AllowedGrantTypesForAuthorizeEndpoint.Contains(request.GrantType))
        {
            LogError("Invalid grant type", request.GrantType, request);
            return(Invalid(request, description: "Invalid response_type"));
        }

        //////////////////////////////////////////////////////////
        // check if PKCE is required and validate parameters
        //////////////////////////////////////////////////////////
        if (request.GrantType == GrantType.AuthorizationCode || request.GrantType == GrantType.Hybrid)
        {
            _logger.LogDebug("Checking for PKCE parameters");

            /////////////////////////////////////////////////////////////////////////////
            // validate code_challenge and code_challenge_method
            /////////////////////////////////////////////////////////////////////////////
            var proofKeyResult = ValidatePkceParameters(request);

            if (proofKeyResult.IsError)
            {
                return(proofKeyResult);
            }
        }

        //////////////////////////////////////////////////////////
        // check response_mode parameter and set response_mode
        //////////////////////////////////////////////////////////

        // check if response_mode parameter is present and valid
        var responseMode = request.Raw.Get(OidcConstants.AuthorizeRequest.ResponseMode);

        if (responseMode.IsPresent())
        {
            if (Constants.SupportedResponseModes.Contains(responseMode))
            {
                if (Constants.AllowedResponseModesForGrantType[request.GrantType].Contains(responseMode))
                {
                    request.ResponseMode = responseMode;
                }
                else
                {
                    LogError("Invalid response_mode for response_type", responseMode, request);
                    return(Invalid(request, OidcConstants.AuthorizeErrors.InvalidRequest, description: "Invalid response_mode for response_type"));
                }
            }
            else
            {
                LogError("Unsupported response_mode", responseMode, request);
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, description: "Invalid response_mode"));
            }
        }


        //////////////////////////////////////////////////////////
        // check if grant type is allowed for client
        //////////////////////////////////////////////////////////
        if (!request.Client.AllowedGrantTypes.Contains(request.GrantType))
        {
            LogError("Invalid grant type for client", request.GrantType, request);
            return(Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, "Invalid grant type for client"));
        }

        //////////////////////////////////////////////////////////
        // check if response type contains an access token,
        // and if client is allowed to request access token via browser
        //////////////////////////////////////////////////////////
        var responseTypes = responseType.FromSpaceSeparatedString();

        if (responseTypes.Contains(OidcConstants.ResponseTypes.Token))
        {
            if (!request.Client.AllowAccessTokensViaBrowser)
            {
                LogError("Client requested access token - but client is not configured to receive access tokens via browser", request);
                return(Invalid(request, description: "Client not configured to receive access tokens via browser"));
            }
        }

        return(Valid(request));
    }
 public void code_id_token_token_combo2()
 {
     ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();
     string x = "code id_token token";
     string y = "token id_token code";
     var result = comparer.Equals(x, y);
     result.Should().BeTrue();
 }