コード例 #1
0
    /// <summary>
    /// String comparison between issuer and authority (trailing slash ignored).
    /// </summary>
    /// <param name="issuerName"></param>
    /// <param name="expectedAuthority"></param>
    /// <returns></returns>
    public AuthorityValidationResult IsIssuerNameValid(string issuerName, string expectedAuthority)
    {
        if (string.IsNullOrWhiteSpace(issuerName))
        {
            return(AuthorityValidationResult.CreateError("Issuer name is missing"));
        }

        if (string.Equals(issuerName.RemoveTrailingSlash(), expectedAuthority.RemoveTrailingSlash(), _stringComparison))
        {
            return(AuthorityValidationResult.SuccessResult);
        }

        return(AuthorityValidationResult.CreateError("Issuer name does not match authority: " + issuerName));
    }
コード例 #2
0
    /// <summary>
    /// String "starts with" comparison between endpoint and allowed authorities.
    /// </summary>
    /// <param name="endpoint"></param>
    /// <param name="allowedAuthorities"></param>
    /// <returns></returns>
    public AuthorityValidationResult IsEndpointValid(string endpoint, IEnumerable <string> allowedAuthorities)
    {
        if (string.IsNullOrEmpty(endpoint))
        {
            return(AuthorityValidationResult.CreateError("endpoint is empty"));
        }

        foreach (string authority in allowedAuthorities)
        {
            if (endpoint.StartsWith(authority, _stringComparison))
            {
                return(AuthorityValidationResult.SuccessResult);
            }
        }

        return(AuthorityValidationResult.CreateError($"Endpoint belongs to different authority: {endpoint}"));
    }
コード例 #3
0
    private string Validate(DiscoveryPolicy policy)
    {
        if (policy.ValidateIssuerName)
        {
            IAuthorityValidationStrategy strategy = policy.AuthorityValidationStrategy ?? DiscoveryPolicy.DefaultAuthorityValidationStrategy;

            AuthorityValidationResult issuerValidationResult = strategy.IsIssuerNameValid(Issuer, policy.Authority);

            if (!issuerValidationResult.Success)
            {
                return(issuerValidationResult.ErrorMessage);
            }
        }

        var error = ValidateEndpoints(Json, policy);

        if (error.IsPresent())
        {
            return(error);
        }

        return(string.Empty);
    }
コード例 #4
0
    /// <inheritdoc/>
    public AuthorityValidationResult IsIssuerNameValid(string issuerName, string expectedAuthority)
    {
        if (!Uri.TryCreate(expectedAuthority.RemoveTrailingSlash(), UriKind.Absolute, out var expectedAuthorityUrl))
        {
            throw new ArgumentOutOfRangeException("Authority must be a valid URL.", nameof(expectedAuthority));
        }

        if (string.IsNullOrWhiteSpace(issuerName))
        {
            return(AuthorityValidationResult.CreateError("Issuer name is missing"));
        }

        if (!Uri.TryCreate(issuerName.RemoveTrailingSlash(), UriKind.Absolute, out var issuerUrl))
        {
            return(AuthorityValidationResult.CreateError("Issuer name is not a valid URL"));
        }

        if (expectedAuthorityUrl.Equals(issuerUrl))
        {
            return(AuthorityValidationResult.SuccessResult);
        }

        return(AuthorityValidationResult.CreateError("Issuer name does not match authority: " + issuerName));
    }
コード例 #5
0
    /// <summary>
    /// Validates the endoints and jwks_uri according to the security policy.
    /// </summary>
    /// <param name="json">The json.</param>
    /// <param name="policy">The policy.</param>
    /// <returns></returns>
    public string ValidateEndpoints(JsonElement json, DiscoveryPolicy policy)
    {
        // allowed hosts
        var allowedHosts = new HashSet <string>(policy.AdditionalEndpointBaseAddresses.Select(e => new Uri(e).Authority))
        {
            new Uri(policy.Authority).Authority
        };

        // allowed authorities (hosts + base address)
        var allowedAuthorities = new HashSet <string>(policy.AdditionalEndpointBaseAddresses)
        {
            policy.Authority
        };

        foreach (var element in json.EnumerateObject())
        {
            if (element.Name.EndsWith("endpoint", StringComparison.OrdinalIgnoreCase) ||
                element.Name.Equals(OidcConstants.Discovery.JwksUri, StringComparison.OrdinalIgnoreCase) ||
                element.Name.Equals(OidcConstants.Discovery.CheckSessionIframe, StringComparison.OrdinalIgnoreCase))
            {
                var endpoint = element.Value.ToString();

                var isValidUri = Uri.TryCreate(endpoint, UriKind.Absolute, out Uri uri);
                if (!isValidUri)
                {
                    return($"Malformed endpoint: {endpoint}");
                }

                if (!DiscoveryEndpoint.IsValidScheme(uri))
                {
                    return($"Malformed endpoint: {endpoint}");
                }

                if (!DiscoveryEndpoint.IsSecureScheme(uri, policy))
                {
                    return($"Endpoint does not use HTTPS: {endpoint}");
                }

                if (policy.ValidateEndpoints)
                {
                    // if endpoint is on exclude list, don't validate
                    if (policy.EndpointValidationExcludeList.Contains(element.Name))
                    {
                        continue;
                    }

                    bool isAllowed = false;
                    foreach (var host in allowedHosts)
                    {
                        if (string.Equals(host, uri.Authority))
                        {
                            isAllowed = true;
                        }
                    }

                    if (!isAllowed)
                    {
                        return($"Endpoint is on a different host than authority: {endpoint}");
                    }

                    IAuthorityValidationStrategy strategy = policy.AuthorityValidationStrategy ?? DiscoveryPolicy.DefaultAuthorityValidationStrategy;
                    AuthorityValidationResult    endpointValidationResult = strategy.IsEndpointValid(endpoint, allowedAuthorities);
                    if (!endpointValidationResult.Success)
                    {
                        return(endpointValidationResult.ErrorMessage);
                    }
                }
            }
        }

        if (policy.RequireKeySet)
        {
            if (string.IsNullOrWhiteSpace(JwksUri))
            {
                return("Keyset is missing");
            }
        }

        return(string.Empty);
    }