mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 06:21:44 +01:00
Merge pull request #1418 from NicolasDorier/refactor/greenfield-classes
Rename classes in Greenfield Authentication, use different AuthenticationScheme for Basic versus APIKey
This commit is contained in:
commit
927c09ff7b
19 changed files with 118 additions and 88 deletions
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Security.APIKeys;
|
||||
using BTCPayServer.Security.GreenField;
|
||||
using BTCPayServer.Tests.Logging;
|
||||
using BTCPayServer.Views.Manage;
|
||||
using Newtonsoft.Json;
|
||||
|
|
|
@ -46,15 +46,13 @@ namespace BTCPayServer.Tests
|
|||
Assert.Single(apiKeyData.Permissions);
|
||||
|
||||
//a client using Basic Auth has no business here
|
||||
await AssertHttpError(404, async () => await clientBasic.GetCurrentAPIKeyInfo());
|
||||
await AssertHttpError(401, async () => await clientBasic.GetCurrentAPIKeyInfo());
|
||||
|
||||
//revoke current api key
|
||||
await client.RevokeCurrentAPIKeyInfo();
|
||||
await AssertHttpError(401, async () => await client.GetCurrentAPIKeyInfo());
|
||||
//a client using Basic Auth has no business here
|
||||
await AssertHttpError(404, async () => await clientBasic.RevokeCurrentAPIKeyInfo());
|
||||
|
||||
|
||||
await AssertHttpError(401, async () => await clientBasic.RevokeCurrentAPIKeyInfo());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@ using BTCPayServer.Client;
|
|||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Security;
|
||||
using BTCPayServer.Security.APIKeys;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using BTCPayServer.Security.GreenField;
|
||||
|
||||
namespace BTCPayServer.Controllers.RestApi
|
||||
namespace BTCPayServer.Controllers.GreenField
|
||||
{
|
||||
[ApiController]
|
||||
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
[Authorize(AuthenticationSchemes = AuthenticationSchemes.GreenfieldAPIKeys)]
|
||||
public class ApiKeysController : ControllerBase
|
||||
{
|
||||
private readonly APIKeyRepository _apiKeyRepository;
|
||||
|
@ -36,7 +36,7 @@ namespace BTCPayServer.Controllers.RestApi
|
|||
}
|
||||
|
||||
[HttpDelete("~/api/v1/api-keys/current")]
|
||||
[Authorize(Policy = Policies.Unrestricted, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
[Authorize(Policy = Policies.Unrestricted, AuthenticationSchemes = AuthenticationSchemes.GreenfieldAPIKeys)]
|
||||
public async Task<ActionResult<ApiKeyData>> RevokeKey()
|
||||
{
|
||||
if (!ControllerContext.HttpContext.GetAPIKey(out var apiKey))
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace BTCPayServer.Controllers.RestApi
|
||||
namespace BTCPayServer.Controllers.GreenField
|
||||
{
|
||||
/// <summary>
|
||||
/// this controller serves as a testing endpoint for our api key unit tests
|
|
@ -8,7 +8,7 @@ using BTCPayServer.Data;
|
|||
using BTCPayServer.Events;
|
||||
using BTCPayServer.Logging;
|
||||
using BTCPayServer.Security;
|
||||
using BTCPayServer.Security.APIKeys;
|
||||
using BTCPayServer.Security.GreenField;
|
||||
using BTCPayServer.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
@ -17,7 +17,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|||
using NicolasDorier.RateLimits;
|
||||
using BTCPayServer.Client;
|
||||
|
||||
namespace BTCPayServer.Controllers.RestApi
|
||||
namespace BTCPayServer.Controllers.GreenField
|
||||
{
|
||||
[ApiController]
|
||||
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
|
@ -74,7 +74,7 @@ namespace BTCPayServer.Controllers.RestApi
|
|||
return BadRequest(CreateValidationProblem(nameof(request.Password), "Password is missing"));
|
||||
var anyAdmin = (await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin)).Any();
|
||||
var policies = await _settingsRepository.GetSettingAsync<PoliciesSettings>() ?? new PoliciesSettings();
|
||||
var isAuth = User.Identity.AuthenticationType == APIKeyConstants.AuthenticationType;
|
||||
var isAuth = User.Identity.AuthenticationType == GreenFieldConstants.AuthenticationType;
|
||||
|
||||
// If registration are locked and that an admin exists, don't accept unauthenticated connection
|
||||
if (anyAdmin && policies.LockSubscription && !isAuth)
|
||||
|
@ -82,7 +82,7 @@ namespace BTCPayServer.Controllers.RestApi
|
|||
|
||||
// Even if subscription are unlocked, it is forbidden to create admin unauthenticated
|
||||
if (anyAdmin && request.IsAdministrator is true && !isAuth)
|
||||
return Forbid(AuthenticationSchemes.Greenfield);
|
||||
return Forbid(AuthenticationSchemes.GreenfieldBasic);
|
||||
// You are de-facto admin if there is no other admin, else you need to be auth and pass policy requirements
|
||||
bool isAdmin = anyAdmin ? (await _authorizationService.AuthorizeAsync(User, null, new PolicyRequirement(Policies.CanModifyServerSettings))).Succeeded
|
||||
&& (await _authorizationService.AuthorizeAsync(User, null, new PolicyRequirement(Policies.Unrestricted))).Succeeded
|
||||
|
@ -90,14 +90,14 @@ namespace BTCPayServer.Controllers.RestApi
|
|||
: true;
|
||||
// You need to be admin to create an admin
|
||||
if (request.IsAdministrator is true && !isAdmin)
|
||||
return Forbid(AuthenticationSchemes.Greenfield);
|
||||
return Forbid(AuthenticationSchemes.GreenfieldBasic);
|
||||
|
||||
if (!isAdmin && policies.LockSubscription)
|
||||
{
|
||||
// If we are not admin and subscriptions are locked, we need to check the Policies.CanCreateUser.Key permission
|
||||
var canCreateUser = (await _authorizationService.AuthorizeAsync(User, null, new PolicyRequirement(Policies.CanCreateUser))).Succeeded;
|
||||
if (!isAuth || !canCreateUser)
|
||||
return Forbid(AuthenticationSchemes.Greenfield);
|
||||
return Forbid(AuthenticationSchemes.GreenfieldBasic);
|
||||
}
|
||||
|
||||
var user = new ApplicationUser
|
|
@ -7,7 +7,7 @@ using BTCPayServer.Client;
|
|||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Security;
|
||||
using BTCPayServer.Security.APIKeys;
|
||||
using BTCPayServer.Security.GreenField;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NBitcoin;
|
||||
|
|
|
@ -19,9 +19,8 @@ using System.Globalization;
|
|||
using BTCPayServer.Security;
|
||||
using BTCPayServer.U2F;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Security.APIKeys;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
using BTCPayServer.Security.GreenField;
|
||||
|
||||
namespace BTCPayServer.Controllers
|
||||
{
|
||||
|
|
|
@ -32,7 +32,6 @@ using BTCPayServer.Payments.Bitcoin;
|
|||
using BTCPayServer.Payments.Changelly;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using BTCPayServer.Security;
|
||||
using BTCPayServer.Security.APIKeys;
|
||||
using BTCPayServer.Services.PaymentRequests;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using NBXplorer.DerivationStrategy;
|
||||
|
@ -44,6 +43,7 @@ using BundlerMinifier.TagHelpers;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using BTCPayServer.Security.Bitpay;
|
||||
using Serilog;
|
||||
using BTCPayServer.Security.GreenField;
|
||||
|
||||
namespace BTCPayServer.Hosting
|
||||
{
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
|
||||
namespace BTCPayServer.Security.Bitpay
|
||||
{
|
||||
public class APIKeyAuthenticationOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@
|
|||
{
|
||||
public const string Cookie = "Identity.Application";
|
||||
public const string Bitpay = "Bitpay";
|
||||
public const string Greenfield = "Greenfield";
|
||||
public const string Greenfield = "Greenfield.APIKeys,Greenfield.Basic";
|
||||
public const string GreenfieldAPIKeys = "Greenfield.APIKeys";
|
||||
public const string GreenfieldBasic = "Greenfield.Basic";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace BTCPayServer.Security.APIKeys
|
||||
namespace BTCPayServer.Security.GreenField
|
||||
{
|
||||
public static class APIKeyExtensions
|
||||
{
|
||||
|
@ -26,7 +26,9 @@ namespace BTCPayServer.Security.APIKeys
|
|||
|
||||
public static AuthenticationBuilder AddAPIKeyAuthentication(this AuthenticationBuilder builder)
|
||||
{
|
||||
builder.AddScheme<APIKeyAuthenticationOptions, APIKeyAuthenticationHandler>(AuthenticationSchemes.Greenfield,
|
||||
builder.AddScheme<GreenFieldAuthenticationOptions, APIKeysAuthenticationHandler>(AuthenticationSchemes.GreenfieldAPIKeys,
|
||||
o => { });
|
||||
builder.AddScheme<GreenFieldAuthenticationOptions, BasicAuthenticationHandler>(AuthenticationSchemes.GreenfieldBasic,
|
||||
o => { });
|
||||
return builder;
|
||||
}
|
||||
|
@ -34,21 +36,21 @@ namespace BTCPayServer.Security.APIKeys
|
|||
public static IServiceCollection AddAPIKeyAuthentication(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddSingleton<APIKeyRepository>();
|
||||
serviceCollection.AddScoped<IAuthorizationHandler, APIKeyAuthorizationHandler>();
|
||||
serviceCollection.AddScoped<IAuthorizationHandler, GreenFieldAuthorizationHandler>();
|
||||
return serviceCollection;
|
||||
}
|
||||
|
||||
public static string[] GetPermissions(this AuthorizationHandlerContext context)
|
||||
{
|
||||
return context.User.Claims.Where(c =>
|
||||
c.Type.Equals(APIKeyConstants.ClaimTypes.Permission, StringComparison.InvariantCultureIgnoreCase))
|
||||
c.Type.Equals(GreenFieldConstants.ClaimTypes.Permission, StringComparison.InvariantCultureIgnoreCase))
|
||||
.Select(claim => claim.Value).ToArray();
|
||||
}
|
||||
|
||||
public static bool HasPermission(this AuthorizationHandlerContext context, Permission permission)
|
||||
{
|
||||
foreach (var claim in context.User.Claims.Where(c =>
|
||||
c.Type.Equals(APIKeyConstants.ClaimTypes.Permission, StringComparison.InvariantCultureIgnoreCase)))
|
||||
c.Type.Equals(GreenFieldConstants.ClaimTypes.Permission, StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
if (Permission.TryParse(claim.Value, out var claimPermission))
|
||||
{
|
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
|||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BTCPayServer.Security.APIKeys
|
||||
namespace BTCPayServer.Security.GreenField
|
||||
{
|
||||
public class APIKeyRepository
|
||||
{
|
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Security.Bitpay;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace BTCPayServer.Security.GreenField
|
||||
{
|
||||
public class APIKeysAuthenticationHandler : AuthenticationHandler<GreenFieldAuthenticationOptions>
|
||||
{
|
||||
private readonly APIKeyRepository _apiKeyRepository;
|
||||
private readonly IOptionsMonitor<IdentityOptions> _identityOptions;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
|
||||
public APIKeysAuthenticationHandler(
|
||||
APIKeyRepository apiKeyRepository,
|
||||
IOptionsMonitor<IdentityOptions> identityOptions,
|
||||
IOptionsMonitor<GreenFieldAuthenticationOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
UserManager<ApplicationUser> userManager) : base(options, logger, encoder, clock)
|
||||
{
|
||||
_apiKeyRepository = apiKeyRepository;
|
||||
_identityOptions = identityOptions;
|
||||
_signInManager = signInManager;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
if (!Context.Request.HttpContext.GetAPIKey(out var apiKey) || string.IsNullOrEmpty(apiKey))
|
||||
return AuthenticateResult.NoResult();
|
||||
|
||||
var key = await _apiKeyRepository.GetKey(apiKey);
|
||||
|
||||
if (key == null)
|
||||
{
|
||||
return AuthenticateResult.Fail("ApiKey authentication failed");
|
||||
}
|
||||
|
||||
List<Claim> claims = new List<Claim>();
|
||||
claims.Add(new Claim(_identityOptions.CurrentValue.ClaimsIdentity.UserIdClaimType, key.UserId));
|
||||
claims.AddRange(Permission.ToPermissions(key.Permissions).Select(permission =>
|
||||
new Claim(GreenFieldConstants.ClaimTypes.Permission, permission.ToString())));
|
||||
return AuthenticateResult.Success(new AuthenticationTicket(
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims, GreenFieldConstants.AuthenticationType)),
|
||||
GreenFieldConstants.AuthenticationType));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,68 +13,34 @@ using Microsoft.AspNetCore.Identity;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace BTCPayServer.Security.APIKeys
|
||||
namespace BTCPayServer.Security.GreenField
|
||||
{
|
||||
public class APIKeyAuthenticationHandler : AuthenticationHandler<APIKeyAuthenticationOptions>
|
||||
public class BasicAuthenticationHandler : AuthenticationHandler<GreenFieldAuthenticationOptions>
|
||||
{
|
||||
private readonly APIKeyRepository _apiKeyRepository;
|
||||
private readonly IOptionsMonitor<IdentityOptions> _identityOptions;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
|
||||
public APIKeyAuthenticationHandler(
|
||||
APIKeyRepository apiKeyRepository,
|
||||
public BasicAuthenticationHandler(
|
||||
IOptionsMonitor<IdentityOptions> identityOptions,
|
||||
IOptionsMonitor<APIKeyAuthenticationOptions> options,
|
||||
IOptionsMonitor<GreenFieldAuthenticationOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
UserManager<ApplicationUser> userManager) : base(options, logger, encoder, clock)
|
||||
{
|
||||
_apiKeyRepository = apiKeyRepository;
|
||||
_identityOptions = identityOptions;
|
||||
_signInManager = signInManager;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
var res = await HandleApiKeyAuthenticateResult();
|
||||
if (res.None)
|
||||
{
|
||||
return await HandleBasicAuthenticateAsync();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private async Task<AuthenticateResult> HandleApiKeyAuthenticateResult()
|
||||
{
|
||||
if (!Context.Request.HttpContext.GetAPIKey(out var apiKey) || string.IsNullOrEmpty(apiKey))
|
||||
return AuthenticateResult.NoResult();
|
||||
|
||||
var key = await _apiKeyRepository.GetKey(apiKey);
|
||||
|
||||
if (key == null)
|
||||
{
|
||||
return AuthenticateResult.Fail("ApiKey authentication failed");
|
||||
}
|
||||
|
||||
List<Claim> claims = new List<Claim>();
|
||||
claims.Add(new Claim(_identityOptions.CurrentValue.ClaimsIdentity.UserIdClaimType, key.UserId));
|
||||
claims.AddRange(Permission.ToPermissions(key.Permissions).Select(permission =>
|
||||
new Claim(APIKeyConstants.ClaimTypes.Permission, permission.ToString())));
|
||||
return AuthenticateResult.Success(new AuthenticationTicket(
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims, APIKeyConstants.AuthenticationType)),
|
||||
APIKeyConstants.AuthenticationType));
|
||||
}
|
||||
|
||||
private async Task<AuthenticateResult> HandleBasicAuthenticateAsync()
|
||||
{
|
||||
string authHeader = Context.Request.Headers["Authorization"];
|
||||
|
||||
if (authHeader == null || !authHeader.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase)) return AuthenticateResult.NoResult();
|
||||
if (authHeader == null || !authHeader.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
|
||||
return AuthenticateResult.NoResult();
|
||||
var encodedUsernamePassword = authHeader.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)[1]?.Trim();
|
||||
var decodedUsernamePassword =
|
||||
Encoding.UTF8.GetString(Convert.FromBase64String(encodedUsernamePassword)).Split(':');
|
||||
|
@ -82,19 +48,20 @@ namespace BTCPayServer.Security.APIKeys
|
|||
var password = decodedUsernamePassword[1];
|
||||
|
||||
var result = await _signInManager.PasswordSignInAsync(username, password, true, true);
|
||||
if (!result.Succeeded) return AuthenticateResult.Fail(result.ToString());
|
||||
if (!result.Succeeded)
|
||||
return AuthenticateResult.Fail(result.ToString());
|
||||
|
||||
var user = await _userManager.FindByNameAsync(username);
|
||||
var claims = new List<Claim>()
|
||||
{
|
||||
new Claim(_identityOptions.CurrentValue.ClaimsIdentity.UserIdClaimType, user.Id),
|
||||
new Claim(APIKeyConstants.ClaimTypes.Permission,
|
||||
new Claim(GreenFieldConstants.ClaimTypes.Permission,
|
||||
Permission.Create(Policies.Unrestricted).ToString())
|
||||
};
|
||||
|
||||
return AuthenticateResult.Success(new AuthenticationTicket(
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims, APIKeyConstants.AuthenticationType)),
|
||||
APIKeyConstants.AuthenticationType));
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims, GreenFieldConstants.AuthenticationType)),
|
||||
GreenFieldConstants.AuthenticationType));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
|
||||
namespace BTCPayServer.Security.GreenField
|
||||
{
|
||||
public class GreenFieldAuthenticationOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
}
|
||||
}
|
|
@ -9,16 +9,16 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace BTCPayServer.Security.APIKeys
|
||||
namespace BTCPayServer.Security.GreenField
|
||||
{
|
||||
public class APIKeyAuthorizationHandler : AuthorizationHandler<PolicyRequirement>
|
||||
public class GreenFieldAuthorizationHandler : AuthorizationHandler<PolicyRequirement>
|
||||
|
||||
{
|
||||
private readonly HttpContext _HttpContext;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly StoreRepository _storeRepository;
|
||||
|
||||
public APIKeyAuthorizationHandler(IHttpContextAccessor httpContextAccessor,
|
||||
public GreenFieldAuthorizationHandler(IHttpContextAccessor httpContextAccessor,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
StoreRepository storeRepository)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ namespace BTCPayServer.Security.APIKeys
|
|||
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
|
||||
PolicyRequirement requirement)
|
||||
{
|
||||
if (context.User.Identity.AuthenticationType != APIKeyConstants.AuthenticationType)
|
||||
if (context.User.Identity.AuthenticationType != GreenFieldConstants.AuthenticationType)
|
||||
return;
|
||||
|
||||
bool success = false;
|
|
@ -1,11 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using BTCPayServer.Client;
|
||||
|
||||
namespace BTCPayServer.Security.APIKeys
|
||||
namespace BTCPayServer.Security.GreenField
|
||||
{
|
||||
public static class APIKeyConstants
|
||||
public static class GreenFieldConstants
|
||||
{
|
||||
public const string AuthenticationType = "APIKey";
|
||||
public const string AuthenticationType = "GreenField";
|
||||
|
||||
public static class ClaimTypes
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
@using BTCPayServer.Client
|
||||
@using BTCPayServer.Controllers
|
||||
@using BTCPayServer.Security.APIKeys
|
||||
@using BTCPayServer.Security.GreenField
|
||||
@model ManageController.AddApiKeyViewModel
|
||||
|
||||
@{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@using BTCPayServer.Client
|
||||
@using BTCPayServer.Controllers
|
||||
@using BTCPayServer.Security.APIKeys
|
||||
@using BTCPayServer.Security.GreenField
|
||||
@model BTCPayServer.Controllers.ManageController.AuthorizeApiKeysViewModel
|
||||
|
||||
@{
|
||||
|
|
Loading…
Add table
Reference in a new issue