Skip to content

Commit d9c066b

Browse files
committed
rebase and implement nonce for returnUrl
1 parent 5d68636 commit d9c066b

8 files changed

Lines changed: 36 additions & 14 deletions

File tree

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: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using ActiveLogin.Authentication.BankId.AspNetCore.DataProtection;
55
using ActiveLogin.Authentication.BankId.AspNetCore.Helpers;
66
using ActiveLogin.Authentication.BankId.AspNetCore.Models;
7+
using ActiveLogin.Authentication.BankId.Core;
78
using ActiveLogin.Authentication.BankId.Core.Flow;
89
using ActiveLogin.Authentication.BankId.Core.UserMessage;
910

@@ -26,8 +27,10 @@ public BankIdUiAuthApiController(
2627
IBankIdUiOptionsProtector uiOptionsProtector,
2728
IBankIdUserMessage bankIdUserMessage,
2829
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
29-
IBankIdUiResultProtector uiAuthResultProtector)
30-
: base(bankIdFlowService, orderRefProtector, qrStartStateProtector, uiOptionsProtector, bankIdUserMessage, bankIdUserMessageLocalizer, uiAuthResultProtector)
30+
IBankIdUiResultProtector uiAuthResultProtector,
31+
IStateStorage stateStorage
32+
)
33+
: base(bankIdFlowService, orderRefProtector, qrStartStateProtector, uiOptionsProtector, bankIdUserMessage, bankIdUserMessageLocalizer, uiAuthResultProtector, stateStorage)
3134
{
3235
}
3336

@@ -43,13 +46,17 @@ public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankId
4346
BankIdFlowInitializeResult bankIdFlowInitializeResult;
4447
try
4548
{
49+
var nonce = Guid.NewGuid().ToString();
4650
var returnRedirectUrl = Url.Action(BankIdConstants.Routes.BankIdAuthInitActionName, BankIdConstants.Routes.BankIdAuthControllerName, new
4751
{
4852
returnUrl = request.ReturnUrl,
49-
uiOptions = request.UiOptions
53+
uiOptions = request.UiOptions,
54+
nonce
5055
}, protocol: Request.Scheme) ?? throw new Exception(BankIdConstants.ErrorMessages.CouldNotGetUrlFor(BankIdConstants.Routes.BankIdAuthControllerName, BankIdConstants.Routes.BankIdAuthInitActionName));
5156

5257
bankIdFlowInitializeResult = await BankIdFlowService.InitializeAuth(uiOptions.ToBankIdFlowOptions(), returnRedirectUrl);
58+
59+
await _stateStorage.SetAsync(new(nonce), returnRedirectUrl);
5360
}
5461
catch (BankIdApiException bankIdApiException)
5562
{

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ IStateStorage stateStorage
2727
{
2828
[HttpGet]
2929
[Route($"/[area]/{BankIdConstants.Routes.BankIdPathName}/{BankIdConstants.Routes.BankIdAuthControllerPath}")]
30-
public Task<ActionResult> Init(string returnUrl, [FromQuery(Name = BankIdConstants.QueryStringParameters.UiOptions)] string protectedUiOptions)
30+
public Task<ActionResult> Init(string returnUrl, [FromQuery(Name = BankIdConstants.QueryStringParameters.UiOptions)] string uiOptions, [FromQuery(Name = "nonce")] string nonce)
3131
{
32-
return Initialize(returnUrl, BankIdConstants.Routes.BankIdAuthApiControllerName, protectedUiOptions, "Init");
32+
return Initialize(returnUrl, BankIdConstants.Routes.BankIdAuthApiControllerName, uiOptions, nonce, "Init");
3333
}
3434
}

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,18 @@ IStateStorage stateStorage
5353
return await stateStorage.GetAsync<T>(stateKey);
5454
}
5555

56-
protected async Task<ActionResult> Initialize(string returnUrl, string apiControllerName, string protectedUiOptions, string viewName)
56+
protected async Task<ActionResult> Initialize(string returnUrl, string apiControllerName, string protectedUiOptions, string nonce, string viewName)
5757
{
5858
Validators.ThrowIfNullOrWhitespace(returnUrl);
5959
Validators.ThrowIfNullOrWhitespace(protectedUiOptions, BankIdConstants.QueryStringParameters.UiOptions);
6060

61+
if (await stateStorage.TryGetAsync<string>(new StateKey(nonce), out var rru)) {
62+
// if we have a saved url, it should be perfect match with returnUrl
63+
if (rru != returnUrl) {
64+
throw new ArgumentException("ReturnUrl mismatch");
65+
}
66+
}
67+
6168
if (!Url.IsLocalUrl(returnUrl))
6269
{
6370
throw new ArgumentException(BankIdConstants.ErrorMessages.InvalidReturnUrl);

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ namespace ActiveLogin.Authentication.BankId.AspNetCore.Areas.ActiveLogin.Control
2222
[NonController]
2323
public class BankIdUiSignApiController : BankIdUiApiControllerBase
2424
{
25-
private readonly IStateStorage stateStorage;
26-
2725
public BankIdUiSignApiController(
2826
IBankIdFlowService bankIdFlowService,
2927
IBankIdUiOrderRefProtector orderRefProtector,
@@ -33,9 +31,8 @@ public BankIdUiSignApiController(
3331
IBankIdUserMessageLocalizer bankIdUserMessageLocalizer,
3432
IBankIdUiResultProtector uiAuthResultProtector,
3533
IStateStorage stateStorage
36-
) : base(bankIdFlowService, orderRefProtector, qrStartStateProtector, uiOptionsProtector, bankIdUserMessage, bankIdUserMessageLocalizer, uiAuthResultProtector)
34+
) : base(bankIdFlowService, orderRefProtector, qrStartStateProtector, uiOptionsProtector, bankIdUserMessage, bankIdUserMessageLocalizer, uiAuthResultProtector, stateStorage)
3735
{
38-
this.stateStorage = stateStorage;
3936
}
4037

4138
[ValidateAntiForgeryToken]
@@ -115,6 +112,6 @@ public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankId
115112
}
116113

117114
var stateKey = new StateKey(cookie);
118-
return stateStorage.GetAsync<BankIdUiSignState>(stateKey);
115+
return _stateStorage.GetAsync<BankIdUiSignState>(stateKey);
119116
}
120117
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ IStateStorage stateStorage
3333
[HttpGet]
3434
[AllowAnonymous]
3535
[Route($"/[area]/{BankIdConstants.Routes.BankIdPathName}/{BankIdConstants.Routes.BankIdSignControllerPath}")]
36-
public Task<ActionResult> Init(string returnUrl, [FromQuery(Name = BankIdConstants.QueryStringParameters.UiOptions)] string protectedUiOptions)
36+
public Task<ActionResult> Init(string returnUrl, [FromQuery(Name = BankIdConstants.QueryStringParameters.UiOptions)] string protectedUiOptions, [FromQuery(Name = "nonce")] string nonce)
3737
{
38-
return Initialize(returnUrl, BankIdConstants.Routes.BankIdSignApiControllerName, protectedUiOptions, "Init");
38+
return Initialize(returnUrl, BankIdConstants.Routes.BankIdSignApiControllerName, protectedUiOptions, nonce, "Init");
3939
}
4040
}

src/ActiveLogin.Authentication.BankId.Core/IStateStorage.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public interface IStateStorage
1414
Task<T?> GetAsync<T>(StateKey key);
1515
Task<bool> TryGetAsync<T>(StateKey key, [NotNullWhen(true)] out T? value);
1616
Task<StateKey> SetAsync<T>(T value);
17+
Task<StateKey> SetAsync<T>(StateKey key, T value);
1718
}
1819

1920
public static class BankIdBuilderStateStorageExtensions

src/ActiveLogin.Authentication.BankId.Core/InMemoryStateStorage.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,10 @@ public Task<StateKey> SetAsync<T>(T value)
3434
cache.Set(stateKey, value, _memoryCacheEntryOptions);
3535
return Task.FromResult(stateKey);
3636
}
37+
38+
public Task<StateKey> SetAsync<T>(StateKey key, T value)
39+
{
40+
cache.Set(key, value, _memoryCacheEntryOptions);
41+
return Task.FromResult(key);
42+
}
3743
}

0 commit comments

Comments
 (0)