Split authentication and authorization
This commit is contained in:
parent
e755f9f96f
commit
64a70e688c
6 changed files with 28 additions and 19 deletions
|
@ -1,4 +1,3 @@
|
|||
using System.Net;
|
||||
using System.Net.Mime;
|
||||
using Iceshrimp.Backend.Controllers.Schemas;
|
||||
using Iceshrimp.Backend.Core.Database;
|
||||
|
@ -19,16 +18,15 @@ namespace Iceshrimp.Backend.Controllers;
|
|||
[Route("/api/iceshrimp/v1/auth")]
|
||||
public class AuthController(DatabaseContext db, UserService userSvc) : Controller {
|
||||
[HttpGet]
|
||||
[Authentication(false)]
|
||||
[Authenticate]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AuthResponse))]
|
||||
public IActionResult GetAuthStatus() {
|
||||
var session = Request.HttpContext.GetSession();
|
||||
|
||||
if (session == null) {
|
||||
if (session == null)
|
||||
return Ok(new AuthResponse {
|
||||
Status = AuthStatusEnum.Guest
|
||||
});
|
||||
}
|
||||
|
||||
return Ok(new AuthResponse {
|
||||
Status = session.Active ? AuthStatusEnum.Authenticated : AuthStatusEnum.TwoFactor,
|
||||
|
|
|
@ -39,6 +39,7 @@ public static class ServiceExtensions {
|
|||
services.AddSingleton<QueueService>();
|
||||
services.AddSingleton<ErrorHandlerMiddleware>();
|
||||
services.AddSingleton<RequestBufferingMiddleware>();
|
||||
services.AddSingleton<AuthorizationMiddleware>();
|
||||
|
||||
// Hosted services = long running background tasks
|
||||
// Note: These need to be added as a singleton as well to ensure data consistency
|
||||
|
|
|
@ -12,6 +12,7 @@ public static class WebApplicationExtensions {
|
|||
return app.UseMiddleware<ErrorHandlerMiddleware>()
|
||||
.UseMiddleware<RequestBufferingMiddleware>()
|
||||
.UseMiddleware<AuthenticationMiddleware>()
|
||||
.UseMiddleware<AuthorizationMiddleware>()
|
||||
.UseMiddleware<AuthorizedFetchMiddleware>();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Iceshrimp.Backend.Core.Database;
|
||||
using Iceshrimp.Backend.Core.Database.Tables;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
|
@ -6,20 +5,15 @@ using Microsoft.EntityFrameworkCore;
|
|||
|
||||
namespace Iceshrimp.Backend.Core.Middleware;
|
||||
|
||||
public class AuthenticationMiddleware(
|
||||
[SuppressMessage("ReSharper", "SuggestBaseTypeForParameterInConstructor")]
|
||||
DatabaseContext db
|
||||
) : IMiddleware {
|
||||
public class AuthenticationMiddleware(DatabaseContext db) : IMiddleware {
|
||||
public async Task InvokeAsync(HttpContext ctx, RequestDelegate next) {
|
||||
var endpoint = ctx.Features.Get<IEndpointFeature>()?.Endpoint;
|
||||
var attribute = endpoint?.Metadata.GetMetadata<AuthenticationAttribute>();
|
||||
var attribute = endpoint?.Metadata.GetMetadata<AuthenticateAttribute>();
|
||||
|
||||
if (attribute != null) {
|
||||
var request = ctx.Request;
|
||||
var header = request.Headers.Authorization.ToString();
|
||||
if (!header.ToLowerInvariant().StartsWith("bearer ")) {
|
||||
if (attribute.Required)
|
||||
throw GracefulException.Unauthorized("Missing bearer token in authorization header");
|
||||
await next(ctx);
|
||||
return;
|
||||
}
|
||||
|
@ -27,11 +21,10 @@ public class AuthenticationMiddleware(
|
|||
var token = header[7..];
|
||||
var session = await db.Sessions.Include(p => p.User).FirstOrDefaultAsync(p => p.Token == token);
|
||||
if (session == null) {
|
||||
if (attribute.Required)
|
||||
throw GracefulException.Forbidden("Bearer token is invalid");
|
||||
await next(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.SetSession(session);
|
||||
}
|
||||
|
||||
|
@ -39,9 +32,7 @@ public class AuthenticationMiddleware(
|
|||
}
|
||||
}
|
||||
|
||||
public class AuthenticationAttribute(bool required = true) : Attribute {
|
||||
public bool Required { get; } = required;
|
||||
}
|
||||
public class AuthenticateAttribute : Attribute;
|
||||
|
||||
public static class HttpContextExtensions {
|
||||
private const string Key = "session";
|
||||
|
|
18
Iceshrimp.Backend/Core/Middleware/AuthorizationMiddleware.cs
Normal file
18
Iceshrimp.Backend/Core/Middleware/AuthorizationMiddleware.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using Microsoft.AspNetCore.Http.Features;
|
||||
|
||||
namespace Iceshrimp.Backend.Core.Middleware;
|
||||
|
||||
public class AuthorizationMiddleware : IMiddleware {
|
||||
public async Task InvokeAsync(HttpContext ctx, RequestDelegate next) {
|
||||
var endpoint = ctx.Features.Get<IEndpointFeature>()?.Endpoint;
|
||||
var attribute = endpoint?.Metadata.GetMetadata<AuthorizeAttribute>();
|
||||
|
||||
if (attribute != null)
|
||||
if (ctx.GetSession() is not { Active: true })
|
||||
throw GracefulException.Forbidden("This method requires an authenticated user");
|
||||
|
||||
await next(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
public class AuthorizeAttribute : Attribute;
|
Loading…
Add table
Reference in a new issue