You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
5.1 KiB
136 lines
5.1 KiB
6 years ago
|
using System;
|
||
10 years ago
|
using System.Text;
|
||
|
using Nancy;
|
||
12 years ago
|
using Nancy.Authentication.Basic;
|
||
10 years ago
|
using Nancy.Authentication.Forms;
|
||
12 years ago
|
using Nancy.Bootstrapper;
|
||
6 years ago
|
using Nancy.Cookies;
|
||
10 years ago
|
using Nancy.Cryptography;
|
||
6 years ago
|
using NzbDrone.Common.Extensions;
|
||
10 years ago
|
using NzbDrone.Core.Authentication;
|
||
|
using NzbDrone.Core.Configuration;
|
||
6 years ago
|
using Radarr.Http.Extensions;
|
||
|
using Radarr.Http.Extensions.Pipelines;
|
||
12 years ago
|
|
||
6 years ago
|
namespace Radarr.Http.Authentication
|
||
12 years ago
|
{
|
||
11 years ago
|
public class EnableAuthInNancy : IRegisterNancyPipeline
|
||
12 years ago
|
{
|
||
|
private readonly IAuthenticationService _authenticationService;
|
||
10 years ago
|
private readonly IConfigService _configService;
|
||
|
private readonly IConfigFileProvider _configFileProvider;
|
||
6 years ago
|
private FormsAuthenticationConfiguration FormsAuthConfig;
|
||
12 years ago
|
|
||
10 years ago
|
public EnableAuthInNancy(IAuthenticationService authenticationService,
|
||
|
IConfigService configService,
|
||
|
IConfigFileProvider configFileProvider)
|
||
12 years ago
|
{
|
||
|
_authenticationService = authenticationService;
|
||
10 years ago
|
_configService = configService;
|
||
|
_configFileProvider = configFileProvider;
|
||
12 years ago
|
}
|
||
|
|
||
8 years ago
|
public int Order => 10;
|
||
8 years ago
|
|
||
12 years ago
|
public void Register(IPipelines pipelines)
|
||
|
{
|
||
10 years ago
|
if (_configFileProvider.AuthenticationMethod == AuthenticationType.Forms)
|
||
|
{
|
||
8 years ago
|
RegisterFormsAuth(pipelines);
|
||
6 years ago
|
pipelines.AfterRequest.AddItemToEndOfPipeline((Action<NancyContext>)SlidingAuthenticationForFormsAuth);
|
||
10 years ago
|
}
|
||
|
|
||
|
else if (_configFileProvider.AuthenticationMethod == AuthenticationType.Basic)
|
||
|
{
|
||
8 years ago
|
pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(_authenticationService, "Radarr"));
|
||
10 years ago
|
}
|
||
|
|
||
6 years ago
|
pipelines.BeforeRequest.AddItemToEndOfPipeline((Func<NancyContext, Response>)RequiresAuthentication);
|
||
|
pipelines.AfterRequest.AddItemToEndOfPipeline((Action<NancyContext>)RemoveLoginHooksForApiCalls);
|
||
12 years ago
|
}
|
||
|
|
||
|
private Response RequiresAuthentication(NancyContext context)
|
||
|
{
|
||
|
Response response = null;
|
||
11 years ago
|
|
||
11 years ago
|
if (!_authenticationService.IsAuthenticated(context))
|
||
12 years ago
|
{
|
||
|
response = new Response { StatusCode = HttpStatusCode.Unauthorized };
|
||
|
}
|
||
|
|
||
|
return response;
|
||
|
}
|
||
10 years ago
|
|
||
|
private void RegisterFormsAuth(IPipelines pipelines)
|
||
|
{
|
||
6 years ago
|
FormsAuthentication.FormsAuthenticationCookieName = "RadarrAuth";
|
||
|
|
||
10 years ago
|
var cryptographyConfiguration = new CryptographyConfiguration(
|
||
|
new RijndaelEncryptionProvider(new PassphraseKeyGenerator(_configService.RijndaelPassphrase, Encoding.ASCII.GetBytes(_configService.RijndaelSalt))),
|
||
|
new DefaultHmacProvider(new PassphraseKeyGenerator(_configService.HmacPassphrase, Encoding.ASCII.GetBytes(_configService.HmacSalt)))
|
||
|
);
|
||
|
|
||
6 years ago
|
FormsAuthConfig = new FormsAuthenticationConfiguration
|
||
10 years ago
|
{
|
||
10 years ago
|
RedirectUrl = _configFileProvider.UrlBase + "/login",
|
||
10 years ago
|
UserMapper = _authenticationService,
|
||
6 years ago
|
Path = GetCookiePath(),
|
||
10 years ago
|
CryptographyConfiguration = cryptographyConfiguration
|
||
6 years ago
|
};
|
||
|
|
||
|
FormsAuthentication.Enable(pipelines, FormsAuthConfig);
|
||
10 years ago
|
}
|
||
|
|
||
|
private void RemoveLoginHooksForApiCalls(NancyContext context)
|
||
|
{
|
||
|
if (context.Request.IsApiRequest())
|
||
|
{
|
||
10 years ago
|
if ((context.Response.StatusCode == HttpStatusCode.SeeOther &&
|
||
8 years ago
|
context.Response.Headers["Location"].StartsWith($"{_configFileProvider.UrlBase}/login", StringComparison.InvariantCultureIgnoreCase)) ||
|
||
10 years ago
|
context.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||
|
{
|
||
|
context.Response = new { Error = "Unauthorized" }.AsResponse(HttpStatusCode.Unauthorized);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
6 years ago
|
|
||
|
private void SlidingAuthenticationForFormsAuth(NancyContext context)
|
||
|
{
|
||
|
if (context.CurrentUser == null)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var formsAuthCookieName = FormsAuthentication.FormsAuthenticationCookieName;
|
||
|
|
||
|
if (!context.Request.Path.Equals("/logout") &&
|
||
|
context.Request.Cookies.ContainsKey(formsAuthCookieName))
|
||
|
{
|
||
|
var formsAuthCookieValue = context.Request.Cookies[formsAuthCookieName];
|
||
|
|
||
|
if (FormsAuthentication.DecryptAndValidateAuthenticationCookie(formsAuthCookieValue, FormsAuthConfig).IsNotNullOrWhiteSpace())
|
||
|
{
|
||
|
var formsAuthCookie = new NancyCookie(formsAuthCookieName, formsAuthCookieValue, true, false, DateTime.UtcNow.AddDays(7))
|
||
|
{
|
||
|
Path = GetCookiePath()
|
||
|
};
|
||
|
|
||
|
context.Response.WithCookie(formsAuthCookie);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private string GetCookiePath()
|
||
|
{
|
||
|
var urlBase = _configFileProvider.UrlBase;
|
||
|
|
||
|
if (urlBase.IsNullOrWhiteSpace())
|
||
|
{
|
||
|
return "/";
|
||
|
}
|
||
|
|
||
|
return urlBase;
|
||
|
}
|
||
12 years ago
|
}
|
||
10 years ago
|
}
|