Implemented proper node authentication
This commit is contained in:
8
MoonlightServers.Daemon/Helpers/TokenAuthOptions.cs
Normal file
8
MoonlightServers.Daemon/Helpers/TokenAuthOptions.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
|
||||
namespace MoonlightServers.Daemon.Helpers;
|
||||
|
||||
public class TokenAuthOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
public string Token { get; set; }
|
||||
}
|
||||
49
MoonlightServers.Daemon/Helpers/TokenAuthScheme.cs
Normal file
49
MoonlightServers.Daemon/Helpers/TokenAuthScheme.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace MoonlightServers.Daemon.Helpers;
|
||||
|
||||
public class TokenAuthScheme : AuthenticationHandler<TokenAuthOptions>
|
||||
{
|
||||
public TokenAuthScheme(IOptionsMonitor<TokenAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder,
|
||||
ISystemClock clock) : base(options, logger, encoder, clock)
|
||||
{
|
||||
}
|
||||
|
||||
public TokenAuthScheme(IOptionsMonitor<TokenAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder) : base(
|
||||
options, logger, encoder)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
if (!Request.Headers.ContainsKey("Authorization"))
|
||||
return Task.FromResult(AuthenticateResult.NoResult());
|
||||
|
||||
var authHeaderValue = Request.Headers["Authorization"].FirstOrDefault();
|
||||
|
||||
if (string.IsNullOrEmpty(authHeaderValue))
|
||||
return Task.FromResult(AuthenticateResult.NoResult());
|
||||
|
||||
if (!authHeaderValue.Contains("Bearer "))
|
||||
return Task.FromResult(AuthenticateResult.NoResult());
|
||||
|
||||
var providedToken = authHeaderValue
|
||||
.Replace("Bearer ", "")
|
||||
.Trim();
|
||||
|
||||
if (providedToken != Options.Token)
|
||||
return Task.FromResult(AuthenticateResult.NoResult());
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Success(
|
||||
new AuthenticationTicket(
|
||||
new ClaimsPrincipal(
|
||||
new ClaimsIdentity("token")
|
||||
),
|
||||
"token"
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -58,37 +58,13 @@ public class RemoteService
|
||||
BaseAddress = new Uri(formattedUrl)
|
||||
};
|
||||
|
||||
var jwt = GenerateJwt(configuration);
|
||||
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwt}");
|
||||
httpClient.DefaultRequestHeaders.Add(
|
||||
"Authorization",
|
||||
$"Bearer {configuration.Security.TokenId}.{configuration.Security.Token}"
|
||||
);
|
||||
|
||||
return new HttpApiClient(httpClient);
|
||||
}
|
||||
|
||||
private string GenerateJwt(AppConfiguration configuration)
|
||||
{
|
||||
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
|
||||
|
||||
var securityTokenDesc = new SecurityTokenDescriptor()
|
||||
{
|
||||
Expires = DateTime.UtcNow.AddYears(1), // TODO: Document somewhere
|
||||
IssuedAt = DateTime.UtcNow,
|
||||
Issuer = configuration.Security.TokenId,
|
||||
Audience = configuration.Remote.Url,
|
||||
NotBefore = DateTime.UtcNow.AddSeconds(-1),
|
||||
SigningCredentials = new SigningCredentials(
|
||||
new SymmetricSecurityKey(
|
||||
Encoding.UTF8.GetBytes(configuration.Security.Token)
|
||||
),
|
||||
SecurityAlgorithms.HmacSha256
|
||||
)
|
||||
};
|
||||
|
||||
var securityToken = jwtSecurityTokenHandler.CreateJwtSecurityToken(securityTokenDesc);
|
||||
|
||||
securityToken.Header.Add("kid", configuration.Security.TokenId);
|
||||
|
||||
return jwtSecurityTokenHandler.WriteToken(securityToken);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,15 +1,11 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Docker.DotNet;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using MoonCore.Configuration;
|
||||
using MoonCore.EnvConfiguration;
|
||||
using MoonCore.Extended.Extensions;
|
||||
using MoonCore.Extensions;
|
||||
using MoonCore.Helpers;
|
||||
using MoonCore.Services;
|
||||
using MoonlightServers.Daemon.Configuration;
|
||||
using MoonlightServers.Daemon.Helpers;
|
||||
using MoonlightServers.Daemon.Http.Hubs;
|
||||
using MoonlightServers.Daemon.Services;
|
||||
|
||||
@@ -91,7 +87,7 @@ public class Startup
|
||||
{
|
||||
options.Limits.MaxRequestBodySize = ByteConverter.FromMegaBytes(Configuration.Files.UploadLimit).Bytes;
|
||||
});
|
||||
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -137,7 +133,7 @@ public class Startup
|
||||
private async Task SetupAppConfiguration()
|
||||
{
|
||||
var configurationBuilder = new ConfigurationBuilder();
|
||||
|
||||
|
||||
// Ensure configuration file exists
|
||||
var jsonFilePath = PathBuilder.File(Directory.GetCurrentDirectory(), "storage", "app.json");
|
||||
|
||||
@@ -147,7 +143,7 @@ public class Startup
|
||||
configurationBuilder.AddJsonFile(
|
||||
jsonFilePath
|
||||
);
|
||||
|
||||
|
||||
configurationBuilder.AddEnvironmentVariables(prefix: "MOONLIGHT_", separator: "_");
|
||||
|
||||
var configurationRoot = configurationBuilder.Build();
|
||||
@@ -311,32 +307,22 @@ public class Startup
|
||||
private Task RegisterAuth()
|
||||
{
|
||||
WebApplicationBuilder.Services
|
||||
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
.AddAuthentication("token")
|
||||
.AddScheme<TokenAuthOptions, TokenAuthScheme>("token", options =>
|
||||
{
|
||||
options.TokenValidationParameters = new()
|
||||
{
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
|
||||
Configuration.Security.Token
|
||||
)),
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidateLifetime = true,
|
||||
ValidateAudience = false,
|
||||
ValidateIssuer = false,
|
||||
ClockSkew = TimeSpan.Zero
|
||||
};
|
||||
options.Token = Configuration.Security.Token;
|
||||
});
|
||||
|
||||
|
||||
WebApplicationBuilder.Services.AddAuthorization();
|
||||
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
private Task UseAuth()
|
||||
{
|
||||
WebApplication.UseAuthentication();
|
||||
WebApplication.UseAuthorization();
|
||||
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user