aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaus Vium <clausvium@gmail.com>2019-11-23 16:31:02 +0100
committerClaus Vium <clausvium@gmail.com>2019-11-23 16:31:02 +0100
commit3f651de24c76f9980fac690e51fa93b3d1163f72 (patch)
treebf6dea80f4a76c2f3e7147918ee56460b0cdc181
parent05b7e2280843f25e48c2300b135f171aee0a54ea (diff)
Add authentication and remove versioning
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs58
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj5
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthService.cs17
-rw-r--r--Emby.Server.Implementations/MvcRoutePrefix.cs2
-rw-r--r--Jellyfin.Api/Auth/CustomAuthenticationHandler.cs53
-rw-r--r--Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs35
-rw-r--r--Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedRequirement.cs8
-rw-r--r--Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationHandler.cs18
-rw-r--r--Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationRequirement.cs9
-rw-r--r--Jellyfin.Api/BaseJellyfinApiController.cs11
-rw-r--r--Jellyfin.Api/Controllers/StartupController.cs25
-rw-r--r--Jellyfin.Api/Jellyfin.Api.csproj34
-rw-r--r--Jellyfin.Api/Models/Startup/StartupConfigurationDto.cs (renamed from Jellyfin.Api/Models/Startup/StartupConfiguration.cs)2
-rw-r--r--Jellyfin.Api/Models/Startup/StartupUserDto.cs (renamed from Jellyfin.Api/Models/Startup/StartupUser.cs)2
-rw-r--r--MediaBrowser.Controller/Net/IAuthService.cs3
15 files changed, 232 insertions, 50 deletions
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 3d2d61225..9227ef61b 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -47,6 +47,10 @@ using Emby.Server.Implementations.Session;
using Emby.Server.Implementations.SocketSharp;
using Emby.Server.Implementations.TV;
using Emby.Server.Implementations.Updates;
+using Jellyfin.Api.Auth;
+using Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy;
+using Jellyfin.Api.Auth.RequiresElevationPolicy;
+using Jellyfin.Api.Controllers;
using MediaBrowser.Api;
using MediaBrowser.Common;
using MediaBrowser.Common.Configuration;
@@ -104,11 +108,14 @@ using MediaBrowser.Providers.Subtitles;
using MediaBrowser.Providers.TV.TheTVDB;
using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -660,25 +667,45 @@ namespace Emby.Server.Implementations
services.AddHttpContextAccessor();
services.AddMvc(opts =>
{
- opts.UseGeneralRoutePrefix("emby", "emby/emby", "api/v{version:apiVersion}");
+ var policy = new AuthorizationPolicyBuilder()
+ .RequireAuthenticatedUser()
+ .Build();
+ opts.Filters.Add(new AuthorizeFilter(policy));
+ opts.EnableEndpointRouting = false;
+ opts.UseGeneralRoutePrefix(ServerConfigurationManager.Configuration.BaseUrl.TrimStart('/'));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
- .AddApplicationPart(Assembly.Load("Jellyfin.Api"));
- services.AddApiVersioning(opt => opt.ReportApiVersions = true);
+ .ConfigureApplicationPartManager(a => a.ApplicationParts.Clear()) // Clear app parts to avoid other assemblies being picked up
+ .AddApplicationPart(typeof(StartupController).Assembly)
+ .AddControllersAsServices();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Jellyfin API", Version = "v1" });
- c.DocInclusionPredicate((docName, apiDesc) =>
- {
- if (!apiDesc.TryGetMethodInfo(out var methodInfo))
- {
- return false;
- }
+ });
+
+ services.AddSingleton<IAuthorizationHandler, FirstTimeSetupOrElevatedHandler>();
+ services.AddSingleton<IAuthorizationHandler, RequiresElevationHandler>();
- // A bit of a hack to make Swagger pick the versioned endpoints instead of the legacy emby endpoints
- return methodInfo.DeclaringType?.BaseType == typeof(ControllerBase) &&
- apiDesc.RelativePath.Contains("api/v");
- });
+ // configure custom legacy authentication
+ services.AddAuthentication("CustomAuthentication")
+ .AddScheme<AuthenticationSchemeOptions, CustomAuthenticationHandler>("CustomAuthentication", null);
+
+ services.AddAuthorizationCore(options =>
+ {
+ options.AddPolicy(
+ "RequiresElevation",
+ policy =>
+ {
+ policy.AddAuthenticationSchemes("CustomAuthentication");
+ policy.AddRequirements(new RequiresElevationRequirement());
+ });
+ options.AddPolicy(
+ "FirstTimeSetupOrElevated",
+ policy =>
+ {
+ policy.AddAuthenticationSchemes("CustomAuthentication");
+ policy.AddRequirements(new FirstTimeSetupOrElevatedRequirement());
+ });
});
// Merge the external ServiceCollection into ASP.NET DI
@@ -686,6 +713,7 @@ namespace Emby.Server.Implementations
})
.Configure(app =>
{
+ app.UseDeveloperExceptionPage();
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
@@ -698,9 +726,9 @@ namespace Emby.Server.Implementations
app.UseWebSockets();
app.UseResponseCompression();
-
// TODO app.UseMiddleware<WebSocketMiddleware>();
app.Use(ExecuteWebsocketHandlerAsync);
+ //app.UseAuthentication();
app.UseMvc();
app.Use(ExecuteHttpHandlerAsync);
})
@@ -938,7 +966,7 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IAuthorizationContext>(authContext);
serviceCollection.AddSingleton<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
- AuthService = new AuthService(authContext, ServerConfigurationManager, SessionManager, NetworkManager);
+ AuthService = new AuthService(LoggerFactory, authContext, ServerConfigurationManager, SessionManager, NetworkManager);
serviceCollection.AddSingleton(AuthService);
SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(LibraryManager, LoggerFactory, ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory);
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 26301b379..e7164342c 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -21,6 +21,9 @@
<ItemGroup>
<PackageReference Include="IPNetwork2" Version="2.4.0.126" />
+ <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
+ <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.0.0" />
+ <PackageReference Include="Microsoft.AspNetCore.Authorization.Policy" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
@@ -38,7 +41,7 @@
<PackageReference Include="ServiceStack.Text.Core" Version="5.6.0" />
<PackageReference Include="sharpcompress" Version="0.24.0" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.0.1" />
- <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc2" />
+ <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
</ItemGroup>
<ItemGroup>
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
index 93a61fe67..81dab83d5 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using Emby.Server.Implementations.SocketSharp;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@@ -7,22 +8,27 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.HttpServer.Security
{
public class AuthService : IAuthService
{
+ private readonly ILogger<AuthService> _logger;
private readonly IAuthorizationContext _authorizationContext;
private readonly ISessionManager _sessionManager;
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
public AuthService(
+ ILoggerFactory loggerFactory,
IAuthorizationContext authorizationContext,
IServerConfigurationManager config,
ISessionManager sessionManager,
INetworkManager networkManager)
{
+ _logger = loggerFactory.CreateLogger<AuthService>();
_authorizationContext = authorizationContext;
_config = config;
_sessionManager = sessionManager;
@@ -34,7 +40,14 @@ namespace Emby.Server.Implementations.HttpServer.Security
ValidateUser(request, authAttribtues);
}
- private void ValidateUser(IRequest request, IAuthenticationAttributes authAttribtues)
+ public User Authenticate(HttpRequest request, IAuthenticationAttributes authAttributes)
+ {
+ var req = new WebSocketSharpRequest(request, null, request.Path, _logger);
+ var user = ValidateUser(req, authAttributes);
+ return user;
+ }
+
+ private User ValidateUser(IRequest request, IAuthenticationAttributes authAttribtues)
{
// This code is executed before the service
var auth = _authorizationContext.GetAuthorizationInfo(request);
@@ -81,6 +94,8 @@ namespace Emby.Server.Implementations.HttpServer.Security
request.RemoteIp,
user);
}
+
+ return user;
}
private void ValidateUserAccess(
diff --git a/Emby.Server.Implementations/MvcRoutePrefix.cs b/Emby.Server.Implementations/MvcRoutePrefix.cs
index fb26ae09d..974a2a885 100644
--- a/Emby.Server.Implementations/MvcRoutePrefix.cs
+++ b/Emby.Server.Implementations/MvcRoutePrefix.cs
@@ -12,7 +12,7 @@ namespace Emby.Server.Implementations
opts.Conventions.Insert(0, new RoutePrefixConvention(prefixes));
}
- internal class RoutePrefixConvention : IApplicationModelConvention
+ private class RoutePrefixConvention : IApplicationModelConvention
{
private readonly AttributeRouteModel[] _routePrefixes;
diff --git a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
new file mode 100644
index 000000000..bb6192b03
--- /dev/null
+++ b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
@@ -0,0 +1,53 @@
+using System.Security.Claims;
+using System.Text.Encodings.Web;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Net;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace Jellyfin.Api.Auth
+{
+ public class CustomAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
+ {
+ private readonly IAuthService _authService;
+
+ public CustomAuthenticationHandler(
+ IAuthService authService,
+ IOptionsMonitor<AuthenticationSchemeOptions> options,
+ ILoggerFactory logger,
+ UrlEncoder encoder,
+ ISystemClock clock) : base(options, logger, encoder, clock)
+ {
+ _authService = authService;
+ }
+
+ protected override Task<AuthenticateResult> HandleAuthenticateAsync()
+ {
+ var authenticatedAttribute = new AuthenticatedAttribute();
+ try
+ {
+ var user = _authService.Authenticate(Request, authenticatedAttribute);
+ if (user == null)
+ {
+ return Task.FromResult(AuthenticateResult.Fail("Invalid user"));
+ }
+
+ var claims = new[]
+ {
+ new Claim(ClaimTypes.Name, user.Name),
+ new Claim(ClaimTypes.Role, user.Policy.IsAdministrator ? "Administrator" : "User"),
+ };
+ var identity = new ClaimsIdentity(claims, Scheme.Name);
+ var principal = new ClaimsPrincipal(identity);
+ var ticket = new AuthenticationTicket(principal, Scheme.Name);
+
+ return Task.FromResult(AuthenticateResult.Success(ticket));
+ }
+ catch (SecurityException ex)
+ {
+ return Task.FromResult(AuthenticateResult.Fail(ex));
+ }
+ }
+ }
+}
diff --git a/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs
new file mode 100644
index 000000000..73925cd61
--- /dev/null
+++ b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs
@@ -0,0 +1,35 @@
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using Microsoft.AspNetCore.Authorization;
+
+namespace Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy
+{
+ public class FirstTimeSetupOrElevatedHandler : AuthorizationHandler<FirstTimeSetupOrElevatedRequirement>
+ {
+ private readonly IConfigurationManager _configurationManager;
+
+ public FirstTimeSetupOrElevatedHandler(IConfigurationManager configurationManager)
+ {
+ _configurationManager = configurationManager;
+ }
+
+ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FirstTimeSetupOrElevatedRequirement firstTimeSetupOrElevatedRequirement)
+ {
+ if (!_configurationManager.CommonConfiguration.IsStartupWizardCompleted)
+ {
+ context.Succeed(firstTimeSetupOrElevatedRequirement);
+ }
+ else if (context.User.IsInRole("Administrator"))
+ {
+ // TODO user role enum
+ context.Succeed(firstTimeSetupOrElevatedRequirement);
+ }
+ else
+ {
+ context.Fail();
+ }
+
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedRequirement.cs b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedRequirement.cs
new file mode 100644
index 000000000..42436c870
--- /dev/null
+++ b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedRequirement.cs
@@ -0,0 +1,8 @@
+using Microsoft.AspNetCore.Authorization;
+
+namespace Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy
+{
+ public class FirstTimeSetupOrElevatedRequirement : IAuthorizationRequirement
+ {
+ }
+}
diff --git a/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationHandler.cs b/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationHandler.cs
new file mode 100644
index 000000000..694827458
--- /dev/null
+++ b/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationHandler.cs
@@ -0,0 +1,18 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+
+namespace Jellyfin.Api.Auth.RequiresElevationPolicy
+{
+ public class RequiresElevationHandler : AuthorizationHandler<RequiresElevationRequirement>
+ {
+ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RequiresElevationRequirement requirement)
+ {
+ if (context.User.IsInRole("Administrator"))
+ {
+ context.Succeed(requirement);
+ }
+
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationRequirement.cs b/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationRequirement.cs
new file mode 100644
index 000000000..dd51cd3c2
--- /dev/null
+++ b/Jellyfin.Api/Auth/RequiresElevationPolicy/RequiresElevationRequirement.cs
@@ -0,0 +1,9 @@
+using Microsoft.AspNetCore.Authorization;
+
+namespace Jellyfin.Api.Auth.RequiresElevationPolicy
+{
+ public class RequiresElevationRequirement : IAuthorizationRequirement
+ {
+
+ }
+}
diff --git a/Jellyfin.Api/BaseJellyfinApiController.cs b/Jellyfin.Api/BaseJellyfinApiController.cs
new file mode 100644
index 000000000..796a8039a
--- /dev/null
+++ b/Jellyfin.Api/BaseJellyfinApiController.cs
@@ -0,0 +1,11 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace Jellyfin.Api
+{
+ [ApiController]
+ [Route("[controller]")]
+ public class BaseJellyfinApiController : ControllerBase
+ {
+
+ }
+}
diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs
index 45e4cd5ac..fb61b8d0b 100644
--- a/Jellyfin.Api/Controllers/StartupController.cs
+++ b/Jellyfin.Api/Controllers/StartupController.cs
@@ -3,12 +3,13 @@ using System.Threading.Tasks;
using Jellyfin.Api.Models.Startup;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Jellyfin.Api.Controllers
{
- [ApiVersion("1")]
- public class StartupController : ControllerBase
+ [Authorize(Policy = "FirstTimeSetupOrElevated")]
+ public class StartupController : BaseJellyfinApiController
{
private readonly IServerConfigurationManager _config;
private readonly IUserManager _userManager;
@@ -28,9 +29,9 @@ namespace Jellyfin.Api.Controllers
}
[HttpGet("Configuration")]
- public StartupConfiguration Get()
+ public StartupConfigurationDto GetStartupConfiguration()
{
- var result = new StartupConfiguration
+ var result = new StartupConfigurationDto
{
UICulture = _config.Configuration.UICulture,
MetadataCountryCode = _config.Configuration.MetadataCountryCode,
@@ -41,7 +42,7 @@ namespace Jellyfin.Api.Controllers
}
[HttpPost("Configuration")]
- public void UpdateInitial([FromForm] string uiCulture, [FromForm] string metadataCountryCode, [FromForm] string preferredMetadataLanguage)
+ public void UpdateInitialConfiguration([FromForm] string uiCulture, [FromForm] string metadataCountryCode, [FromForm] string preferredMetadataLanguage)
{
_config.Configuration.UICulture = uiCulture;
_config.Configuration.MetadataCountryCode = metadataCountryCode;
@@ -50,7 +51,7 @@ namespace Jellyfin.Api.Controllers
}
[HttpPost("RemoteAccess")]
- public void Post([FromForm] bool enableRemoteAccess, [FromForm] bool enableAutomaticPortMapping)
+ public void SetRemoteAccess([FromForm] bool enableRemoteAccess, [FromForm] bool enableAutomaticPortMapping)
{
_config.Configuration.EnableRemoteAccess = enableRemoteAccess;
_config.Configuration.EnableUPnP = enableAutomaticPortMapping;
@@ -58,11 +59,11 @@ namespace Jellyfin.Api.Controllers
}
[HttpGet("User")]
- public StartupUser GetUser()
+ public StartupUserDto GetUser()
{
var user = _userManager.Users.First();
- return new StartupUser
+ return new StartupUserDto
{
Name = user.Name,
Password = user.Password
@@ -70,17 +71,17 @@ namespace Jellyfin.Api.Controllers
}
[HttpPost("User")]
- public async Task UpdateUser([FromForm] StartupUser startupUser)
+ public async Task UpdateUser([FromForm] StartupUserDto startupUserDto)
{
var user = _userManager.Users.First();
- user.Name = startupUser.Name;
+ user.Name = startupUserDto.Name;
_userManager.UpdateUser(user);
- if (!string.IsNullOrEmpty(startupUser.Password))
+ if (!string.IsNullOrEmpty(startupUserDto.Password))
{
- await _userManager.ChangePassword(user, startupUser.Password).ConfigureAwait(false);
+ await _userManager.ChangePassword(user, startupUserDto.Password).ConfigureAwait(false);
}
}
}
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index 7a7e49e30..647004cb6 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -1,18 +1,16 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <TargetFramework>netstandard2.0</TargetFramework>
- <OutputType>Library</OutputType>
- </PropertyGroup>
-
- <ItemGroup>
- <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
- <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="3.1.3" />
- <PackageReference Include="NETStandard.Library" Version="2.0.3" />
- </ItemGroup>
-
- <ItemGroup>
- <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
- </ItemGroup>
-
-</Project>
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.1</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
+ <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Jellyfin.Api/Models/Startup/StartupConfiguration.cs b/Jellyfin.Api/Models/Startup/StartupConfigurationDto.cs
index 08dd59a17..769d2e1bb 100644
--- a/Jellyfin.Api/Models/Startup/StartupConfiguration.cs
+++ b/Jellyfin.Api/Models/Startup/StartupConfigurationDto.cs
@@ -1,6 +1,6 @@
namespace Jellyfin.Api.Models.Startup
{
- public class StartupConfiguration
+ public class StartupConfigurationDto
{
public string UICulture { get; set; }
public string MetadataCountryCode { get; set; }
diff --git a/Jellyfin.Api/Models/Startup/StartupUser.cs b/Jellyfin.Api/Models/Startup/StartupUserDto.cs
index 93a09e865..c7c2e8cb0 100644
--- a/Jellyfin.Api/Models/Startup/StartupUser.cs
+++ b/Jellyfin.Api/Models/Startup/StartupUserDto.cs
@@ -1,6 +1,6 @@
namespace Jellyfin.Api.Models.Startup
{
- public class StartupUser
+ public class StartupUserDto
{
public string Name { get; set; }
public string Password { get; set; }
diff --git a/MediaBrowser.Controller/Net/IAuthService.cs b/MediaBrowser.Controller/Net/IAuthService.cs
index 142f1d91c..4c9120e0c 100644
--- a/MediaBrowser.Controller/Net/IAuthService.cs
+++ b/MediaBrowser.Controller/Net/IAuthService.cs
@@ -1,9 +1,12 @@
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller.Net
{
public interface IAuthService
{
void Authenticate(IRequest request, IAuthenticationAttributes authAttribtues);
+ User Authenticate(HttpRequest request, IAuthenticationAttributes authAttribtues);
}
}