Fix Plugin Local Client authorization when user is provided (#3401)

* Fix Plugin Local Client authorization when user is provided

* 1337 hax
This commit is contained in:
Andrew Camilleri
2022-02-02 12:09:08 +01:00
committed by GitHub
parent 8e5b7d2578
commit c07fcc171c
2 changed files with 79 additions and 3 deletions

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
@@ -11,9 +12,12 @@ using BTCPayServer.Client.Models;
using BTCPayServer.Data;
using BTCPayServer.Security.Greenfield;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NBitcoin;
using NBXplorer.Models;
@@ -52,6 +56,7 @@ namespace BTCPayServer.Controllers.Greenfield
private readonly GreenfieldPullPaymentController _greenfieldPullPaymentController;
private readonly UIHomeController _homeController;
private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController;
private readonly IServiceProvider _serviceProvider;
public BTCPayServerClientFactory(StoreRepository storeRepository,
IOptionsMonitor<IdentityOptions> identityOptions,
@@ -73,7 +78,8 @@ namespace BTCPayServer.Controllers.Greenfield
GreenfieldStoreWebhooksController storeWebhooksController,
GreenfieldPullPaymentController greenfieldPullPaymentController,
UIHomeController homeController,
GreenfieldStorePaymentMethodsController storePaymentMethodsController)
GreenfieldStorePaymentMethodsController storePaymentMethodsController,
IServiceProvider serviceProvider)
{
_storeRepository = storeRepository;
_identityOptions = identityOptions;
@@ -96,6 +102,7 @@ namespace BTCPayServer.Controllers.Greenfield
_greenfieldPullPaymentController = greenfieldPullPaymentController;
_homeController = homeController;
_storePaymentMethodsController = storePaymentMethodsController;
_serviceProvider = serviceProvider;
}
public async Task<BTCPayServerClient> Create(string userId, params string[] storeIds)
@@ -113,7 +120,7 @@ namespace BTCPayServer.Controllers.Greenfield
claims.AddRange((await _userManager.GetRolesAsync(user)).Select(s =>
new Claim(_identityOptions.CurrentValue.ClaimsIdentity.RoleClaimType, s)));
context.User =
new ClaimsPrincipal(new ClaimsIdentity(claims, GreenfieldConstants.AuthenticationType));
new ClaimsPrincipal(new ClaimsIdentity(claims, $"Local{GreenfieldConstants.AuthenticationType}WithUser"));
}
else
{
@@ -132,6 +139,7 @@ namespace BTCPayServer.Controllers.Greenfield
}
return new LocalBTCPayServerClient(
_serviceProvider,
_chainPaymentMethodsController,
_storeOnChainWalletsController,
_healthController,
@@ -176,7 +184,9 @@ namespace BTCPayServer.Controllers.Greenfield
private readonly UIHomeController _homeController;
private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController;
public LocalBTCPayServerClient(GreenfieldStoreOnChainPaymentMethodsController chainPaymentMethodsController,
public LocalBTCPayServerClient(
IServiceProvider serviceProvider,
GreenfieldStoreOnChainPaymentMethodsController chainPaymentMethodsController,
GreenfieldStoreOnChainWalletsController storeOnChainWalletsController,
GreenfieldHealthController healthController,
GreenfieldPaymentRequestsController paymentRequestController,
@@ -223,12 +233,56 @@ namespace BTCPayServer.Controllers.Greenfield
greenFieldServerInfoController, greenfieldPullPaymentController, storesController, homeController,
lightningNodeApiController, storeLightningNodeApiController as ControllerBase, storePaymentMethodsController
};
var authoverride = new DefaultAuthorizationService(
serviceProvider.GetRequiredService<IAuthorizationPolicyProvider>(),
new AuthHandlerProvider(
serviceProvider.GetRequiredService<StoreRepository>(),
serviceProvider.GetRequiredService<UserManager<ApplicationUser>>(),
httpContextAccessor
),
serviceProvider.GetRequiredService<ILogger<DefaultAuthorizationService>>(),
serviceProvider.GetRequiredService<IAuthorizationHandlerContextFactory>(),
serviceProvider.GetRequiredService<IAuthorizationEvaluator>(),
serviceProvider.GetRequiredService<IOptions<AuthorizationOptions>>()
);
foreach (var controller in controllers)
{
controller.ControllerContext.HttpContext = httpContextAccessor.HttpContext;
var authInterface = typeof(IAuthorizationService);
foreach (FieldInfo fieldInfo in controller.GetType().GetFields().Where(info => authInterface.IsAssignableFrom(info.FieldType)))
{
fieldInfo.SetValue(controller, authoverride);
}
}
}
class AuthHandlerProvider : IAuthorizationHandlerProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly UserManager<ApplicationUser> _userManager;
private readonly StoreRepository _storeRepository;
public AuthHandlerProvider(StoreRepository storeRepository, UserManager<ApplicationUser> userManager, IHttpContextAccessor httpContextAccessor)
{
_storeRepository = storeRepository;
_userManager = userManager;
_httpContextAccessor = httpContextAccessor;
}
public Task<IEnumerable<IAuthorizationHandler>> GetHandlersAsync(AuthorizationHandlerContext context)
{
return Task.FromResult<IEnumerable<IAuthorizationHandler>>(new IAuthorizationHandler[]
{
new LocalGreenfieldAuthorizationHandler(_httpContextAccessor, _userManager, _storeRepository)
});
}
}
protected override HttpRequestMessage CreateHttpRequest(string path,
Dictionary<string, object> queryPayload = null, HttpMethod method = null)
{