mirror of
https://github.com/Radarr/Radarr
synced 2025-12-06 08:28:50 +01:00
Fix: incompatibility with reverse proxy forward auth providers
Signed-off-by: solidDoWant <fred.heinecke@yahoo.com>
This commit is contained in:
parent
ff6a69701f
commit
32e5aee9bf
4 changed files with 63 additions and 2 deletions
|
|
@ -27,6 +27,7 @@ function addContentType(ajaxOptions) {
|
||||||
|
|
||||||
export default function createAjaxRequest(originalAjaxOptions) {
|
export default function createAjaxRequest(originalAjaxOptions) {
|
||||||
const requestXHR = new window.XMLHttpRequest();
|
const requestXHR = new window.XMLHttpRequest();
|
||||||
|
requestXHR.withCredentials = true; // Needed for CORS requests with cookies, which some reverse proxies with forward auth require
|
||||||
let aborted = false;
|
let aborted = false;
|
||||||
let complete = false;
|
let complete = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ public class ServerOptions
|
||||||
{
|
{
|
||||||
public string UrlBase { get; set; }
|
public string UrlBase { get; set; }
|
||||||
public string BindAddress { get; set; }
|
public string BindAddress { get; set; }
|
||||||
|
public string AllowedCORSOrigins { get; set; } // TODO
|
||||||
public int? Port { get; set; }
|
public int? Port { get; set; }
|
||||||
public bool? EnableSsl { get; set; }
|
public bool? EnableSsl { get; set; }
|
||||||
public int? SslPort { get; set; }
|
public int? SslPort { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ public interface IConfigFileProvider : IHandleAsync<ApplicationStartedEvent>,
|
||||||
void EnsureDefaultConfigFile();
|
void EnsureDefaultConfigFile();
|
||||||
|
|
||||||
string BindAddress { get; }
|
string BindAddress { get; }
|
||||||
|
string AllowedCORSOrigins { get; }
|
||||||
int Port { get; }
|
int Port { get; }
|
||||||
int SslPort { get; }
|
int SslPort { get; }
|
||||||
bool EnableSsl { get; }
|
bool EnableSsl { get; }
|
||||||
|
|
@ -174,6 +175,8 @@ public string BindAddress
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string AllowedCORSOrigins => _serverOptions.AllowedCORSOrigins ?? GetValue("AllowedCORSOrigins", "*");
|
||||||
|
|
||||||
public int Port => _serverOptions.Port ?? GetValueInt("Port", 7878);
|
public int Port => _serverOptions.Port ?? GetValueInt("Port", 7878);
|
||||||
|
|
||||||
public int SslPort => _serverOptions.SslPort ?? GetValueInt("SslPort", 9898);
|
public int SslPort => _serverOptions.SslPort ?? GetValueInt("SslPort", 9898);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using DryIoc;
|
using DryIoc;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
|
@ -11,6 +12,7 @@
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using NLog.Extensions.Logging;
|
using NLog.Extensions.Logging;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
|
@ -70,15 +72,18 @@ public void ConfigureServices(IServiceCollection services)
|
||||||
|
|
||||||
services.AddCors(options =>
|
services.AddCors(options =>
|
||||||
{
|
{
|
||||||
|
// Origin policy will be added after configuration is complete, because it depends on config file values
|
||||||
options.AddPolicy(VersionedApiControllerAttribute.API_CORS_POLICY,
|
options.AddPolicy(VersionedApiControllerAttribute.API_CORS_POLICY,
|
||||||
builder =>
|
builder =>
|
||||||
builder.AllowAnyOrigin()
|
builder
|
||||||
|
.AllowCredentials()
|
||||||
.AllowAnyMethod()
|
.AllowAnyMethod()
|
||||||
.AllowAnyHeader());
|
.AllowAnyHeader());
|
||||||
|
|
||||||
options.AddPolicy("AllowGet",
|
options.AddPolicy("AllowGet",
|
||||||
builder =>
|
builder =>
|
||||||
builder.AllowAnyOrigin()
|
builder
|
||||||
|
.AllowCredentials()
|
||||||
.WithMethods("GET", "OPTIONS")
|
.WithMethods("GET", "OPTIONS")
|
||||||
.AllowAnyHeader());
|
.AllowAnyHeader());
|
||||||
});
|
});
|
||||||
|
|
@ -194,6 +199,8 @@ public void ConfigureServices(IServiceCollection services)
|
||||||
|
|
||||||
services.AddAppAuthentication();
|
services.AddAppAuthentication();
|
||||||
|
|
||||||
|
services.ConfigureOptions<CORSOriginConfigurator>();
|
||||||
|
|
||||||
services.PostConfigure<ApiBehaviorOptions>(options =>
|
services.PostConfigure<ApiBehaviorOptions>(options =>
|
||||||
{
|
{
|
||||||
var builtInFactory = options.InvalidModelStateResponseFactory;
|
var builtInFactory = options.InvalidModelStateResponseFactory;
|
||||||
|
|
@ -327,3 +334,52 @@ private void EnsureSingleInstance(bool isService, IStartupContext startupContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CORSOriginConfigurator : IPostConfigureOptions<CorsOptions>
|
||||||
|
{
|
||||||
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
|
private readonly NLog.Logger _logger;
|
||||||
|
|
||||||
|
public CORSOriginConfigurator(IConfigFileProvider configFileProvider, NLog.Logger logger)
|
||||||
|
{
|
||||||
|
_configFileProvider = configFileProvider;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostConfigure(string name, CorsOptions options) => PostConfigure(options);
|
||||||
|
|
||||||
|
public void PostConfigure(CorsOptions options)
|
||||||
|
{
|
||||||
|
_logger.Info("Configuring CORS. Allowed origins: {0}", _configFileProvider.AllowedCORSOrigins);
|
||||||
|
options.GetPolicy(VersionedApiControllerAttribute.API_CORS_POLICY).IsOriginAllowed = CorsOriginCheck;
|
||||||
|
options.GetPolicy("AllowGet").IsOriginAllowed = CorsOriginCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool CorsOriginCheck(string requestOrigin)
|
||||||
|
{
|
||||||
|
var allowedOrigin = _configFileProvider.AllowedCORSOrigins;
|
||||||
|
if (allowedOrigin.Equals(CorsConstants.AnyOrigin, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(requestOrigin))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowedOriginAsUri = new Uri(allowedOrigin);
|
||||||
|
Uri requestOriginAsUri;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
requestOriginAsUri = new Uri(requestOrigin);
|
||||||
|
}
|
||||||
|
catch (UriFormatException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare the scheme and authority (host + port) of the two URIs, according to RFC 6454
|
||||||
|
return Uri.Compare(allowedOriginAsUri, requestOriginAsUri, UriComponents.SchemeAndServer, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue