mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 13:23:20 -07:00
Swap out the old way of validating the API key with a real middlewear this time.
This commit is contained in:
parent
f222224459
commit
a1c5124269
3 changed files with 107 additions and 41 deletions
105
src/Ombi/ApiKeyMiddlewear.cs
Normal file
105
src/Ombi/ApiKeyMiddlewear.cs
Normal file
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
|
||||
namespace Ombi
|
||||
{
|
||||
public class ApiKeyMiddlewear
|
||||
{
|
||||
public ApiKeyMiddlewear(RequestDelegate next, ISettingsService<OmbiSettings> repo, OmbiUserManager um)
|
||||
{
|
||||
_next = next;
|
||||
_repo = repo;
|
||||
_userManager = um;
|
||||
}
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ISettingsService<OmbiSettings> _repo;
|
||||
private readonly OmbiUserManager _userManager;
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (context.Request.Path.StartsWithSegments(new PathString("/api")))
|
||||
{
|
||||
//Let's check if this is an API Call
|
||||
if (context.Request.Headers.Keys.Contains("ApiKey"))
|
||||
{
|
||||
// validate the supplied API key
|
||||
// Validate it
|
||||
var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
|
||||
await ValidateApiKey(context, _next, headerKey);
|
||||
}
|
||||
else if (context.Request.Query.ContainsKey("apikey"))
|
||||
{
|
||||
if (context.Request.Query.TryGetValue("apikey", out var queryKey))
|
||||
{
|
||||
await ValidateApiKey(context, _next, queryKey);
|
||||
}
|
||||
}
|
||||
// User access token used by the mobile app
|
||||
else if (context.Request.Headers["UserAccessToken"].Any())
|
||||
{
|
||||
var headerKey = context.Request.Headers["UserAccessToken"].FirstOrDefault();
|
||||
await ValidateUserAccessToken(context, _next, headerKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ValidateUserAccessToken(HttpContext context, RequestDelegate next, string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
await context.Response.WriteAsync("Invalid User Access Token");
|
||||
return;
|
||||
}
|
||||
|
||||
var user = await _userManager.Users.FirstOrDefaultAsync(x => x.UserAccessToken == key);
|
||||
if (user == null)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
await context.Response.WriteAsync("Invalid User Access Token");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var identity = new GenericIdentity(user.UserName);
|
||||
var roles = await _userManager.GetRolesAsync(user);
|
||||
var principal = new GenericPrincipal(identity, roles.ToArray());
|
||||
context.User = principal;
|
||||
await next.Invoke(context);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ValidateApiKey(HttpContext context, RequestDelegate next, string key)
|
||||
{
|
||||
var ombiSettings = await _repo.GetSettingsAsync();
|
||||
var valid = ombiSettings.ApiKey.Equals(key, StringComparison.CurrentCultureIgnoreCase);
|
||||
if (!valid)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
await context.Response.WriteAsync("Invalid API Key");
|
||||
}
|
||||
else
|
||||
{
|
||||
var identity = new GenericIdentity("API");
|
||||
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
|
||||
context.User = principal;
|
||||
await next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -217,8 +217,9 @@ namespace Ombi
|
|||
app.UseAuthentication();
|
||||
|
||||
app.UseMiddleware<ErrorHandlingMiddleware>();
|
||||
app.UseMiddleware<ApiKeyMiddlewear>();
|
||||
|
||||
app.ApiKeyMiddlewear(app.ApplicationServices);
|
||||
//app.ApiKeyMiddlewear(app.ApplicationServices);
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
|
|
|
@ -115,46 +115,6 @@ namespace Ombi
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
public static void ApiKeyMiddlewear(this IApplicationBuilder app, IServiceProvider serviceProvider)
|
||||
{
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
if (context.Request.Path.StartsWithSegments(new PathString("/api")))
|
||||
{
|
||||
// Let's check if this is an API Call
|
||||
if (context.Request.Headers["ApiKey"].Any())
|
||||
{
|
||||
// validate the supplied API key
|
||||
// Validate it
|
||||
var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
|
||||
await ValidateApiKey(serviceProvider, context, next, headerKey);
|
||||
}
|
||||
else if (context.Request.Query.ContainsKey("apikey"))
|
||||
{
|
||||
if (context.Request.Query.TryGetValue("apikey", out var queryKey))
|
||||
{
|
||||
await ValidateApiKey(serviceProvider, context, next, queryKey);
|
||||
}
|
||||
}
|
||||
// User access token used by the mobile app
|
||||
else if (context.Request.Headers["UserAccessToken"].Any())
|
||||
{
|
||||
var headerKey = context.Request.Headers["UserAccessToken"].FirstOrDefault();
|
||||
await ValidateUserAccessToken(serviceProvider, context, next, headerKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
await next();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await next();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static async Task ValidateUserAccessToken(IServiceProvider serviceProvider, HttpContext context, Func<Task> next, string key)
|
||||
{
|
||||
if (key.IsNullOrEmpty())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue