コード例 #1
0
        public async Task <ImmutableArray <ValidationResult> > ValidateSettingsAsync(OpenIdValidationSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            var results = ImmutableArray.CreateBuilder <ValidationResult>();

            if (!(string.IsNullOrEmpty(settings.Authority) ^ string.IsNullOrEmpty(settings.Tenant)))
            {
                results.Add(new ValidationResult(T["Either a tenant or an authority must be registered."], new[]
                {
                    nameof(settings.Authority),
                    nameof(settings.Tenant)
                }));
            }

            if (!string.IsNullOrEmpty(settings.Authority))
            {
                if (!Uri.TryCreate(settings.Authority, UriKind.Absolute, out Uri uri) || !uri.IsWellFormedOriginalString())
                {
                    results.Add(new ValidationResult(T["The specified authority is not valid."], new[]
                    {
                        nameof(settings.Authority)
                    }));
                }

                if (!string.IsNullOrEmpty(uri.Query) || !string.IsNullOrEmpty(uri.Fragment))
                {
                    results.Add(new ValidationResult(T["The authority cannot contain a query string or a fragment."], new[]
                    {
                        nameof(settings.Authority)
                    }));
                }
            }

            if (string.IsNullOrEmpty(settings.Authority) && !string.IsNullOrEmpty(settings.Audience))
            {
                results.Add(new ValidationResult(T["No audience can be set when using another tenant."], new[]
                {
                    nameof(settings.Audience)
                }));
            }

            if (!string.IsNullOrEmpty(settings.Authority) && string.IsNullOrEmpty(settings.Audience))
            {
                results.Add(new ValidationResult(T["An audience must be set when configuring the authority."], new[]
                {
                    nameof(settings.Audience)
                }));
            }

            if (!string.IsNullOrEmpty(settings.Audience) &&
                settings.Audience.StartsWith(OpenIdConstants.Prefixes.Tenant, StringComparison.OrdinalIgnoreCase))
            {
                results.Add(new ValidationResult(T["The audience cannot start with the special 'oct:' prefix."], new[]
                {
                    nameof(settings.Audience)
                }));
            }

            // If a tenant was specified, ensure it is valid, that the OpenID server feature
            // was enabled and that at least a scope linked with the current tenant exists.
            if (!string.IsNullOrEmpty(settings.Tenant) &&
                !string.Equals(settings.Tenant, _shellSettings.Name, StringComparison.Ordinal))
            {
                IServiceScope scope;
                if ((scope = await _shellHost.TryGetScopeAsync(settings.Tenant)) == null)
                {
                    results.Add(new ValidationResult(T["The specified tenant is not valid."]));
                }
                else
                {
                    using (scope)
                    {
                        var manager = scope.ServiceProvider.GetService <IOpenIdScopeManager>();
                        if (manager == null)
                        {
                            results.Add(new ValidationResult(T["The specified tenant is not valid."], new[]
                            {
                                nameof(settings.Tenant)
                            }));
                        }
                        else
                        {
                            var resource = OpenIdConstants.Prefixes.Tenant + _shellSettings.Name;
                            var scopes   = await manager.FindByResourceAsync(resource);

                            if (scopes.IsDefaultOrEmpty)
                            {
                                results.Add(new ValidationResult(T["No appropriate scope was found."], new[]
                                {
                                    nameof(settings.Tenant)
                                }));
                            }
                        }
                    }
                }
            }

            return(results.ToImmutable());
        }