Exemple #1
0
        public async Task UpdateSettingsAsync(OpenIdValidationSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            var container = await _siteService.GetSiteSettingsAsync();

            container.Properties[nameof(OpenIdValidationSettings)] = JObject.FromObject(settings);
            await _siteService.UpdateSiteSettingsAsync(container);
        }
Exemple #2
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());
        }
        public async Task <ImmutableArray <ValidationResult> > ValidateSettingsAsync(OpenIdValidationSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

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

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

            if (settings.Authority != null)
            {
                if (!settings.Authority.IsAbsoluteUri || !settings.Authority.IsWellFormedOriginalString())
                {
                    results.Add(new ValidationResult(S["The specified authority is not valid."], new[]
                    {
                        nameof(settings.Authority)
                    }));
                }

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

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

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

            if (settings.Authority == null && settings.DisableTokenTypeValidation)
            {
                results.Add(new ValidationResult(S["Token type validation can only be disabled for remote servers."], new[]
                {
                    nameof(settings.DisableTokenTypeValidation)
                }));
            }

            if (!string.IsNullOrEmpty(settings.Audience) &&
                settings.Audience.StartsWith(OpenIdConstants.Prefixes.Tenant, StringComparison.OrdinalIgnoreCase))
            {
                results.Add(new ValidationResult(S["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))
            {
                if (!_shellHost.TryGetSettings(settings.Tenant, out var shellSettings))
                {
                    results.Add(new ValidationResult(S["The specified tenant is not valid."]));
                }
                else
                {
                    var shellScope = await _shellHost.GetScopeAsync(shellSettings);

                    await shellScope.UsingAsync(async scope =>
                    {
                        var options = scope.ServiceProvider.GetRequiredService <IOptionsMonitor <OpenIddictServerOptions> >().CurrentValue;
                        if (options.UseReferenceAccessTokens)
                        {
                            results.Add(new ValidationResult(S["Selecting a server tenant for which reference access tokens are enabled is currently not supported."], new[]
                            {
                                nameof(settings.Tenant)
                            }));
                        }

                        var manager = scope.ServiceProvider.GetService <IOpenIdScopeManager>();
                        if (manager == null)
                        {
                            results.Add(new ValidationResult(S["The specified tenant is not valid."], new[]
                            {
                                nameof(settings.Tenant)
                            }));
                        }
                        else
                        {
                            var resource = OpenIdConstants.Prefixes.Tenant + _shellSettings.Name;
                            if (!await manager.FindByResourceAsync(resource).AnyAsync())
                            {
                                results.Add(new ValidationResult(S["No appropriate scope was found."], new[]
                                {
                                    nameof(settings.Tenant)
                                }));
                            }
                        }
                    });
                }
            }

            return(results.ToImmutable());
        }