Skip to content

Commit a2f7f58

Browse files
committed
Revert ApiKey authentication
1 parent 7627140 commit a2f7f58

14 files changed

+169
-66
lines changed

src/DragonFly.ApiKeys/DragonFlyBuilderExtensions.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
using DragonFly.ApiKeys.AspNetCore.Services;
99
using DragonFly.ApiKeys.Permissions;
1010
using Microsoft.Extensions.DependencyInjection;
11+
using DragonFly.ApiKeys.Handlers;
1112
using Microsoft.AspNetCore.Authorization;
1213
using DragonFly.AspNetCore.Builders;
13-
using Microsoft.AspNetCore.Builder;
14-
using DragonFly.ApiKeys.Middlewares;
1514

1615
namespace DragonFly.AspNetCore;
1716

@@ -24,6 +23,10 @@ public static IDragonFlyBuilder AddApiKeys(this IDragonFlyBuilder builder)
2423
builder.Services.AddSingleton<MongoIdentityStore>();
2524
builder.Services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
2625

26+
builder.Services.AddAuthentication().AddApiKey(ApiKeyAuthenticationDefaults.AuthenticationScheme);
27+
28+
builder.AddPermissionScheme(ApiKeyAuthenticationDefaults.AuthenticationScheme);
29+
2730
builder.Init(api =>
2831
{
2932
api.Permission()
@@ -36,7 +39,6 @@ public static IDragonFlyBuilder AddApiKeys(this IDragonFlyBuilder builder)
3639
});
3740

3841
builder.AddEndpoint(x => x.MapApiKeyApi());
39-
builder.UseApplicationBuilder(x => x.UseMiddleware<ApiKeysMiddleware>());
4042

4143
return builder;
4244
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/DragonFly
3+
// MIT License
4+
5+
namespace DragonFly.ApiKeys.Handlers;
6+
7+
public static class ApiKeyAuthenticationDefaults
8+
{
9+
public const string AuthenticationScheme = $"{Permission.PolicyPrefix}ApiKey";
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/DragonFly
3+
// MIT License
4+
5+
using Microsoft.AspNetCore.Authentication;
6+
using Microsoft.Extensions.DependencyInjection;
7+
8+
namespace DragonFly.ApiKeys.Handlers;
9+
10+
public static class ApiKeyAuthenticationExtensions
11+
{
12+
public static AuthenticationBuilder AddApiKey(this AuthenticationBuilder builder, string scheme, Action<ApiKeyAuthenticationOptions>? configureOptions = null)
13+
{
14+
builder.Services.AddOptions<ApiKeyAuthenticationOptions>(scheme);
15+
return builder.AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(scheme, null, configureOptions);
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/DragonFly
3+
// MIT License
4+
5+
using System.Security.Claims;
6+
using System.Text.Encodings.Web;
7+
using Microsoft.AspNetCore.Authentication;
8+
using Microsoft.Extensions.Logging;
9+
using Microsoft.Extensions.Options;
10+
11+
namespace DragonFly.ApiKeys.Handlers;
12+
13+
internal class ApiKeyAuthenticationHandler : AuthenticationHandler<ApiKeyAuthenticationOptions>
14+
{
15+
public ApiKeyAuthenticationHandler(
16+
IOptionsMonitor<ApiKeyAuthenticationOptions> options,
17+
ILoggerFactory logger,
18+
UrlEncoder encoder,
19+
IApiKeyService apiKeyService)
20+
: base(options, logger, encoder)
21+
{
22+
ApiKeyService = apiKeyService;
23+
}
24+
25+
/// <summary>
26+
/// ApiKeyService
27+
/// </summary>
28+
private IApiKeyService ApiKeyService { get; }
29+
30+
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
31+
{
32+
string? requestApiKey = Context.Request.Headers["ApiKey"].FirstOrDefault();
33+
34+
if (requestApiKey != null)
35+
{
36+
ApiKey? apiKey = await ApiKeyService.GetApiKey(requestApiKey);
37+
38+
if (apiKey != null)
39+
{
40+
return AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(new ClaimsIdentity([new Claim("Name", $"apikey:{apiKey.Name}"), new Claim("ApiKeyId", apiKey.Id.ToString())], "ApiKey")), Scheme.Name));
41+
}
42+
else
43+
{
44+
return AuthenticateResult.Fail("Invalid api key");
45+
}
46+
}
47+
48+
return AuthenticateResult.NoResult();
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/DragonFly
3+
// MIT License
4+
5+
using Microsoft.AspNetCore.Authentication;
6+
7+
namespace DragonFly.ApiKeys.Handlers;
8+
9+
public class ApiKeyAuthenticationOptions : AuthenticationSchemeOptions
10+
{
11+
12+
}

src/DragonFly.ApiKeys/Middlewares/ApiKeysMiddleware.cs

-44
This file was deleted.

src/DragonFly.AspNetCore/Permissions/AuthorizationEndpointExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public static TBuilder RequirePermission<TBuilder>(this TBuilder builder)
2323
{
2424
return builder.RequireAuthorization(x => x
2525
.RequireAuthenticatedUser()
26-
.AddAuthenticationSchemes(PermissionConstants.AuthenticationScheme)
26+
.AddAuthenticationSchemes(PermissionSchemeManager.GetAll())
2727
);
2828
}
2929
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/DragonFly
3+
// MIT License
4+
5+
using DragonFly.AspNetCore.Builders;
6+
7+
namespace DragonFly.AspNetCore;
8+
9+
public static class BuilderPermissionExtensions
10+
{
11+
/// <summary>
12+
/// Adds permission scheme.
13+
/// </summary>
14+
/// <param name="builder"></param>
15+
/// <param name="scheme"></param>
16+
/// <returns></returns>
17+
public static IDragonFlyBuilder AddPermissionScheme(this IDragonFlyBuilder builder, string scheme)
18+
{
19+
PermissionSchemeManager.Add(scheme);
20+
21+
return builder;
22+
}
23+
}

src/DragonFly.AspNetCore/Permissions/PermissionConstants.cs

-13
This file was deleted.

src/DragonFly.AspNetCore/Permissions/PermissionExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static class PermissionExtensions
1111
{
1212
public static AuthorizationPolicy ToAuthorizationPolicy(this Permission permission)
1313
{
14-
var policy = new AuthorizationPolicyBuilder(PermissionConstants.AuthenticationScheme);
14+
var policy = new AuthorizationPolicyBuilder(PermissionSchemeManager.GetAll());
1515
policy.RequireAuthenticatedUser();
1616
policy.AddRequirements(new PermissionRequirement(permission.Name));
1717

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/DragonFly
3+
// MIT License
4+
5+
namespace DragonFly.AspNetCore;
6+
7+
/// <summary>
8+
/// PermissionSchemeManager
9+
/// </summary>
10+
public static class PermissionSchemeManager
11+
{
12+
private static HashSet<string> _items = new HashSet<string>();
13+
14+
private static string[] _cache = Array.Empty<string>();
15+
16+
/// <summary>
17+
/// Adds scheme.
18+
/// </summary>
19+
/// <param name="scheme"></param>
20+
public static void Add(string scheme)
21+
{
22+
_items.Add(scheme);
23+
24+
_cache = _items.ToArray();
25+
}
26+
27+
/// <summary>
28+
/// Gets available schemes.
29+
/// </summary>
30+
/// <returns></returns>
31+
public static string[] GetAll()
32+
{
33+
return _cache;
34+
}
35+
}

src/DragonFly.Identity/DragonFlyBuilderExtensions.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ public static IDragonFlyBuilder AddMongoDbIdentity(this IDragonFlyBuilder builde
3131
builder.Services.AddSingleton<IPasswordHashGenerator, PasswordHashGenerator>();
3232
builder.Services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
3333

34-
builder.Services.AddAuthentication()
35-
.AddCookie(PermissionConstants.AuthenticationScheme, x => x.LoginPath = "/login");
34+
builder.Services.AddAuthentication(IdentityAuthenticationDefaults.AuthenticationScheme)
35+
.AddCookie(IdentityAuthenticationDefaults.AuthenticationScheme, x => x.LoginPath = "/login");
36+
37+
builder.AddPermissionScheme(IdentityAuthenticationDefaults.AuthenticationScheme);
3638

3739
builder.Init(api =>
3840
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/DragonFly
3+
// MIT License
4+
5+
namespace DragonFly.Identity.Services;
6+
public static class IdentityAuthenticationDefaults
7+
{
8+
public const string AuthenticationScheme = $"{Permission.PolicyPrefix}Identity";
9+
}

src/DragonFly.Identity/Services/LoginService.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public async Task<LoginResult> LoginAsync(string username, string password, bool
8484
//Blazor WebAssembly?
8585
if (HttpContextAccessor.HttpContext?.WebSockets.IsWebSocketRequest == false)
8686
{
87-
await HttpContextAccessor.HttpContext.SignInAsync(PermissionConstants.AuthenticationScheme, principal, new AuthenticationProperties() { IsPersistent = isPersistent });
87+
await HttpContextAccessor.HttpContext.SignInAsync(IdentityAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties() { IsPersistent = isPersistent });
8888
}
8989

9090
return new LoginResult(true) { Username = user.Username, Claims = claims.Select(x=> new ClaimItem(x.Type, x.Value)).ToList() };
@@ -94,7 +94,7 @@ public async Task Logout()
9494
{
9595
if (HttpContextAccessor.HttpContext?.WebSockets.IsWebSocketRequest == false)
9696
{
97-
await HttpContextAccessor.HttpContext!.SignOutAsync(PermissionConstants.AuthenticationScheme);
97+
await HttpContextAccessor.HttpContext!.SignOutAsync(IdentityAuthenticationDefaults.AuthenticationScheme);
9898
}
9999
}
100100

0 commit comments

Comments
 (0)