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()); }