Skip to content

Commit f612b4e

Browse files
committed
feat(#478): replace cookie with storage
1 parent 5c10007 commit f612b4e

28 files changed

Lines changed: 514 additions & 260 deletions

samples/Standalone.MvcSample/Standalone.MvcSample.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@
3131
</ItemGroup>
3232

3333
<ItemGroup>
34-
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
34+
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.23.0" />
3535
</ItemGroup>
3636
</Project>

src/ActiveLogin.Authentication.BankId.AspNetCore/Areas/ActiveLogin/Controllers/BankIdUiApiControllerBase.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using ActiveLogin.Authentication.BankId.AspNetCore.DataProtection;
99
using ActiveLogin.Authentication.BankId.AspNetCore.Helpers;
1010
using ActiveLogin.Authentication.BankId.AspNetCore.Models;
11+
using ActiveLogin.Authentication.BankId.Core;
1112
using ActiveLogin.Authentication.BankId.Core.Flow;
1213
using ActiveLogin.Authentication.BankId.Core.UserMessage;
1314

@@ -25,6 +26,7 @@ public abstract class BankIdUiApiControllerBase : ControllerBase
2526
protected readonly IBankIdUiOrderRefProtector OrderRefProtector;
2627
protected readonly IBankIdQrStartStateProtector QrStartStateProtector;
2728
protected readonly IBankIdUiOptionsProtector UiOptionsProtector;
29+
protected readonly IStateStorage _stateStorage;
2830

2931
private readonly IBankIdUserMessage _bankIdUserMessage;
3032
private readonly IBankIdUserMessageLocalizer _bankIdUserMessageLocalizer;
@@ -38,7 +40,8 @@ protected BankIdUiApiControllerBase(
3840

3941
IBankIdUserMessage bankIdUserMessage,
4042
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
41-
IBankIdUiResultProtector uiAuthResultProtector
43+
IBankIdUiResultProtector uiAuthResultProtector,
44+
IStateStorage stateStorage
4245

4346
)
4447
{
@@ -50,6 +53,7 @@ IBankIdUiResultProtector uiAuthResultProtector
5053
_bankIdUserMessage = bankIdUserMessage;
5154
_bankIdUserMessageLocalizer = bankIdUserMessageLocalizer;
5255
_uiAuthResultProtector = uiAuthResultProtector;
56+
_stateStorage = stateStorage;
5357
}
5458

5559
[ValidateAntiForgeryToken]

src/ActiveLogin.Authentication.BankId.AspNetCore/Areas/ActiveLogin/Controllers/BankIdUiAuthApiController.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using ActiveLogin.Authentication.BankId.AspNetCore.Models;
77
using ActiveLogin.Authentication.BankId.Core.Flow;
88
using ActiveLogin.Authentication.BankId.Core.UserMessage;
9-
9+
using ActiveLogin.Authentication.BankId.Core;
1010
using Microsoft.AspNetCore.Authorization;
1111
using Microsoft.AspNetCore.Mvc;
1212

@@ -26,8 +26,10 @@ public BankIdUiAuthApiController(
2626
IBankIdUiOptionsProtector uiOptionsProtector,
2727
IBankIdUserMessage bankIdUserMessage,
2828
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
29-
IBankIdUiResultProtector uiAuthResultProtector)
30-
: base(bankIdFlowService, orderRefProtector, qrStartStateProtector, uiOptionsProtector, bankIdUserMessage, bankIdUserMessageLocalizer, uiAuthResultProtector)
29+
IBankIdUiResultProtector uiAuthResultProtector,
30+
IStateStorage stateStorage
31+
)
32+
: base(bankIdFlowService, orderRefProtector, qrStartStateProtector, uiOptionsProtector, bankIdUserMessage, bankIdUserMessageLocalizer, uiAuthResultProtector, stateStorage)
3133
{
3234
}
3335

src/ActiveLogin.Authentication.BankId.AspNetCore/Areas/ActiveLogin/Controllers/BankIdUiAuthController.cs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
using ActiveLogin.Authentication.BankId.AspNetCore.Auth;
12
using ActiveLogin.Authentication.BankId.AspNetCore.DataProtection;
3+
using ActiveLogin.Authentication.BankId.AspNetCore.Models;
24
using ActiveLogin.Authentication.BankId.AspNetCore.StateHandling;
5+
using ActiveLogin.Authentication.BankId.Core;
36
using ActiveLogin.Authentication.BankId.Core.UserMessage;
47

58
using Microsoft.AspNetCore.Antiforgery;
69
using Microsoft.AspNetCore.Authorization;
10+
using Microsoft.AspNetCore.Http;
711
using Microsoft.AspNetCore.Mvc;
812
using Microsoft.Extensions.Localization;
913

@@ -12,21 +16,15 @@ namespace ActiveLogin.Authentication.BankId.AspNetCore.Areas.ActiveLogin.Control
1216
[Area(BankIdConstants.Routes.ActiveLoginAreaName)]
1317
[AllowAnonymous]
1418
[NonController]
15-
public class BankIdUiAuthController : BankIdUiControllerBase
19+
public class BankIdUiAuthController(
20+
IAntiforgery antiforgery,
21+
IStringLocalizer<ActiveLoginResources> localizer,
22+
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
23+
IBankIdUiOptionsProtector uiOptionsProtector,
24+
IBankIdInvalidStateHandler bankIdInvalidStateHandler,
25+
IStateStorage stateStorage
26+
) : BankIdUiControllerBase<BankIdUiAuthState>(antiforgery, localizer, bankIdUserMessageLocalizer, uiOptionsProtector, bankIdInvalidStateHandler, stateStorage)
1627
{
17-
public BankIdUiAuthController(
18-
IAntiforgery antiforgery,
19-
IStringLocalizer<ActiveLoginResources> localizer,
20-
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
21-
IBankIdUiOptionsProtector uiOptionsProtector,
22-
IBankIdInvalidStateHandler bankIdInvalidStateHandler,
23-
IBankIdUiStateProtector bankIdUiStateProtector
24-
)
25-
: base(antiforgery, localizer, bankIdUserMessageLocalizer, uiOptionsProtector, bankIdInvalidStateHandler, bankIdUiStateProtector)
26-
{
27-
28-
}
29-
3028
[HttpGet]
3129
[Route($"/[area]/{BankIdConstants.Routes.BankIdPathName}/{BankIdConstants.Routes.BankIdAuthControllerPath}")]
3230
public Task<ActionResult> Init(string returnUrl, [FromQuery(Name = BankIdConstants.QueryStringParameters.UiOptions)] string protectedUiOptions)

src/ActiveLogin.Authentication.BankId.AspNetCore/Areas/ActiveLogin/Controllers/BankIdUiControllerBase.cs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using ActiveLogin.Authentication.BankId.AspNetCore.Models;
66
using ActiveLogin.Authentication.BankId.AspNetCore.Sign;
77
using ActiveLogin.Authentication.BankId.AspNetCore.StateHandling;
8+
using ActiveLogin.Authentication.BankId.Core;
89
using ActiveLogin.Authentication.BankId.Core.UserMessage;
910

1011
using Microsoft.AspNetCore.Antiforgery;
@@ -14,29 +15,42 @@
1415
namespace ActiveLogin.Authentication.BankId.AspNetCore.Areas.ActiveLogin.Controllers;
1516

1617
[NonController]
17-
public abstract class BankIdUiControllerBase : Controller
18+
public abstract class BankIdUiControllerBase<T> : Controller
19+
where T : BankIdUiState
1820
{
1921
private readonly IAntiforgery _antiforgery;
2022
private readonly IStringLocalizer<ActiveLoginResources> _localizer;
2123
private readonly IBankIdUserMessageLocalizer _bankIdUserMessageLocalizer;
2224
private readonly IBankIdUiOptionsProtector _uiOptionsProtector;
2325
private readonly IBankIdInvalidStateHandler _bankIdInvalidStateHandler;
24-
private readonly IBankIdUiStateProtector _bankIdUiStateProtector;
26+
private readonly IStateStorage stateStorage;
2527

26-
protected BankIdUiControllerBase(
28+
public BankIdUiControllerBase(
2729
IAntiforgery antiforgery,
2830
IStringLocalizer<ActiveLoginResources> localizer,
2931
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
3032
IBankIdUiOptionsProtector uiOptionsProtector,
3133
IBankIdInvalidStateHandler bankIdInvalidStateHandler,
32-
IBankIdUiStateProtector bankIdUiStateProtector)
34+
IStateStorage stateStorage
35+
)
3336
{
37+
this.stateStorage = stateStorage;
3438
_antiforgery = antiforgery;
3539
_localizer = localizer;
3640
_bankIdUserMessageLocalizer = bankIdUserMessageLocalizer;
3741
_uiOptionsProtector = uiOptionsProtector;
3842
_bankIdInvalidStateHandler = bankIdInvalidStateHandler;
39-
_bankIdUiStateProtector = bankIdUiStateProtector;
43+
}
44+
45+
protected async Task<T?> GetUIState(BankIdUiOptions uiOptions)
46+
{
47+
var cookie = HttpContext.Request.Cookies[uiOptions.StateKeyCookieName];
48+
if (cookie is null)
49+
{
50+
return default;
51+
}
52+
var stateKey = new StateKey(cookie);
53+
return await stateStorage.GetAsync<T>(stateKey);
4054
}
4155

4256
protected async Task<ActionResult> Initialize(string returnUrl, string apiControllerName, string protectedUiOptions, string viewName)
@@ -58,32 +72,40 @@ protected async Task<ActionResult> Initialize(string returnUrl, string apiContro
5872
return new EmptyResult();
5973
}
6074

61-
var antiforgeryTokens = _antiforgery.GetAndStoreTokens(HttpContext);
75+
var state = await GetUIState(uiOptions);
6276

63-
var protectedState = Request.Cookies[uiOptions.StateCookieName];
64-
if(protectedState == null)
77+
if (state == null)
6578
{
6679
var invalidStateContext = new BankIdInvalidStateContext(uiOptions.CancelReturnUrl);
6780
await _bankIdInvalidStateHandler.HandleAsync(invalidStateContext);
6881

6982
return new EmptyResult();
7083
}
71-
var state = _bankIdUiStateProtector.Unprotect(protectedState);
7284

85+
var antiforgeryTokens = _antiforgery.GetAndStoreTokens(HttpContext);
7386
var viewModel = GetUiViewModel(returnUrl, apiControllerName, protectedUiOptions, uiOptions, state, antiforgeryTokens);
7487

7588
return View(viewName, viewModel);
7689
}
7790

7891
private bool HasStateCookie(BankIdUiOptions uiOptions)
7992
{
80-
if (string.IsNullOrEmpty(uiOptions.StateCookieName)
81-
|| !HttpContext.Request.Cookies.ContainsKey(uiOptions.StateCookieName))
93+
if (string.IsNullOrEmpty(uiOptions.StateKeyCookieName))
94+
{
95+
return false;
96+
}
97+
98+
if (!HttpContext.Request.Cookies.ContainsKey(uiOptions.StateKeyCookieName))
99+
{
100+
return false;
101+
}
102+
103+
if (string.IsNullOrEmpty(HttpContext.Request.Cookies[uiOptions.StateKeyCookieName]))
82104
{
83105
return false;
84106
}
85107

86-
return !string.IsNullOrEmpty(HttpContext.Request.Cookies[uiOptions.StateCookieName]);
108+
return true;
87109
}
88110

89111
private BankIdUiViewModel GetUiViewModel(string returnUrl, string apiControllerName, string protectedUiOptions, BankIdUiOptions unprotectedUiOptions, BankIdUiState uiState, AntiforgeryTokenSet antiforgeryTokens)
@@ -122,7 +144,7 @@ private BankIdUiViewModel GetUiViewModel(string returnUrl, string apiControllerN
122144
var localizedCancelButtonText = _localizer["Cancel_Button"];
123145
var localizedQrCodeImageAltText = _localizer["Qr_Code_Image"];
124146

125-
if(uiState is BankIdUiSignState signState)
147+
if (uiState is BankIdUiSignState signState)
126148
{
127149
var uiSignData = new BankIdUiSignData
128150
{

src/ActiveLogin.Authentication.BankId.AspNetCore/Areas/ActiveLogin/Controllers/BankIdUiSignApiController.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using ActiveLogin.Authentication.BankId.AspNetCore.Helpers;
66
using ActiveLogin.Authentication.BankId.AspNetCore.Models;
77
using ActiveLogin.Authentication.BankId.AspNetCore.Sign;
8+
using ActiveLogin.Authentication.BankId.Core;
89
using ActiveLogin.Authentication.BankId.Core.Flow;
910
using ActiveLogin.Authentication.BankId.Core.Models;
1011
using ActiveLogin.Authentication.BankId.Core.UserMessage;
@@ -21,8 +22,6 @@ namespace ActiveLogin.Authentication.BankId.AspNetCore.Areas.ActiveLogin.Control
2122
[NonController]
2223
public class BankIdUiSignApiController : BankIdUiApiControllerBase
2324
{
24-
private readonly IBankIdUiStateProtector _bankIdUiStateProtector;
25-
2625
public BankIdUiSignApiController(
2726
IBankIdFlowService bankIdFlowService,
2827
IBankIdUiOrderRefProtector orderRefProtector,
@@ -31,10 +30,9 @@ public BankIdUiSignApiController(
3130
IBankIdUserMessage bankIdUserMessage,
3231
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
3332
IBankIdUiResultProtector uiAuthResultProtector,
34-
IBankIdUiStateProtector bankIdUiStateProtector)
35-
: base(bankIdFlowService, orderRefProtector, qrStartStateProtector, uiOptionsProtector, bankIdUserMessage, bankIdUserMessageLocalizer, uiAuthResultProtector)
33+
IStateStorage stateStorage
34+
) : base(bankIdFlowService, orderRefProtector, qrStartStateProtector, uiOptionsProtector, bankIdUserMessage, bankIdUserMessageLocalizer, uiAuthResultProtector, stateStorage)
3635
{
37-
_bankIdUiStateProtector = bankIdUiStateProtector;
3836
}
3937

4038
[ValidateAntiForgeryToken]
@@ -46,8 +44,8 @@ public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankId
4644

4745
var uiOptions = UiOptionsProtector.Unprotect(request.UiOptions);
4846

49-
var state = GetStateFromCookie(uiOptions);
50-
if(state == null)
47+
var state = await GetState(uiOptions);
48+
if (state == null)
5149
{
5250
throw new InvalidOperationException(BankIdConstants.ErrorMessages.InvalidStateCookie);
5351
}
@@ -105,14 +103,15 @@ public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankId
105103
}
106104
}
107105

108-
private BankIdUiSignState? GetStateFromCookie(BankIdUiOptions uiOptions)
106+
private Task<BankIdUiSignState?> GetState(BankIdUiOptions uiOptions)
109107
{
110-
var protectedState = Request.Cookies[uiOptions.StateCookieName];
111-
if (protectedState == null)
108+
var cookie = Request.Cookies[uiOptions.StateKeyCookieName];
109+
if (cookie == null)
112110
{
113-
throw new InvalidOperationException(BankIdConstants.ErrorMessages.InvalidStateCookie);
111+
return Task.FromResult<BankIdUiSignState?>(null);
114112
}
115113

116-
return _bankIdUiStateProtector.Unprotect(protectedState) as BankIdUiSignState;
114+
var stateKey = new StateKey(cookie);
115+
return _stateStorage.GetAsync<BankIdUiSignState>(stateKey);
117116
}
118117
}

src/ActiveLogin.Authentication.BankId.AspNetCore/Areas/ActiveLogin/Controllers/BankIdUiSignController.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
using ActiveLogin.Authentication.BankId.AspNetCore.Areas.ActiveLogin.Models;
12
using ActiveLogin.Authentication.BankId.AspNetCore.DataProtection;
3+
using ActiveLogin.Authentication.BankId.AspNetCore.Models;
4+
using ActiveLogin.Authentication.BankId.AspNetCore.Sign;
25
using ActiveLogin.Authentication.BankId.AspNetCore.StateHandling;
6+
using ActiveLogin.Authentication.BankId.Core;
37
using ActiveLogin.Authentication.BankId.Core.UserMessage;
48

59
using Microsoft.AspNetCore.Antiforgery;
610
using Microsoft.AspNetCore.Authorization;
11+
using Microsoft.AspNetCore.Http;
712
using Microsoft.AspNetCore.Mvc;
813
using Microsoft.Extensions.Localization;
914

@@ -12,19 +17,17 @@ namespace ActiveLogin.Authentication.BankId.AspNetCore.Areas.ActiveLogin.Control
1217
[Area(BankIdConstants.Routes.ActiveLoginAreaName)]
1318
[AllowAnonymous]
1419
[NonController]
15-
public class BankIdUiSignController : BankIdUiControllerBase
20+
public class BankIdUiSignController : BankIdUiControllerBase<BankIdUiSignState>
1621
{
1722
public BankIdUiSignController(
1823
IAntiforgery antiforgery,
1924
IStringLocalizer<ActiveLoginResources> localizer,
2025
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
2126
IBankIdUiOptionsProtector uiOptionsProtector,
2227
IBankIdInvalidStateHandler bankIdInvalidStateHandler,
23-
IBankIdUiStateProtector bankIdUiStateProtector
24-
)
25-
: base(antiforgery, localizer, bankIdUserMessageLocalizer, uiOptionsProtector, bankIdInvalidStateHandler, bankIdUiStateProtector)
28+
IStateStorage stateStorage
29+
) : base(antiforgery, localizer, bankIdUserMessageLocalizer, uiOptionsProtector, bankIdInvalidStateHandler, stateStorage)
2630
{
27-
2831
}
2932

3033
[HttpGet]

src/ActiveLogin.Authentication.BankId.AspNetCore/Auth/AuthenticationBuilderBankIdExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using ActiveLogin.Authentication.BankId.AspNetCore.ApplicationFeatureProviders;
22
using ActiveLogin.Authentication.BankId.AspNetCore.ClaimsTransformation;
33
using ActiveLogin.Authentication.BankId.AspNetCore.DataProtection;
4+
using ActiveLogin.Authentication.BankId.AspNetCore.Sign;
45
using ActiveLogin.Authentication.BankId.Core;
56
using ActiveLogin.Authentication.BankId.Core.Requirements;
67
using ActiveLogin.Authentication.BankId.Core.UserData;
@@ -72,7 +73,7 @@ private static void AddBankIdAuthDefaultServices(IBankIdAuthBuilder builder)
7273

7374
BankIdCommonConfiguration.AddDefaultServices(services);
7475

75-
services.AddTransient<IBankIdUiStateProtector, BankIdUiStateProtector>();
76+
services.AddSingleton<IStateStorage, InMemoryStateStorage>();
7677
services.AddTransient<IBankIdUiResultProtector, BankIdUiResultProtector>();
7778

7879
builder.AddClaimsTransformer<BankIdDefaultClaimsTransformer>();

0 commit comments

Comments
 (0)