Skip to content

Commit 0d8b624

Browse files
elinohlssonElin Fokine
andauthored
UiOptions in cookie - Use session cookie, add support for sign and payment (#521)
* Store one instance of the UiOptions cookie. Make it a session cookie. Delete the session cookie in auth handler callback method. * Create and delete UiOptions cookie for sign and payments as well. * Return empty result to init view if we do not have a ui options cookie. Same behaviour as for the state cookie. --------- Co-authored-by: Elin Fokine <ElinO@activesolution.se>
1 parent 7d3a504 commit 0d8b624

24 files changed

Lines changed: 184 additions & 332 deletions

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

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,14 @@ public async Task<ActionResult> Status(BankIdUiApiStatusRequest request)
6262
{
6363
Validators.ThrowIfNullOrWhitespace(request.OrderRef, nameof(request.OrderRef));
6464
Validators.ThrowIfNullOrWhitespace(request.ReturnUrl, nameof(request.ReturnUrl));
65-
Validators.ThrowIfNullOrWhitespace(request.UiOptions, nameof(request.UiOptions));
6665

6766
if (!Url.IsLocalUrl(request.ReturnUrl))
6867
{
6968
throw new Exception(BankIdConstants.ErrorMessages.InvalidReturnUrl);
7069
}
7170

7271
var orderRef = OrderRefProtector.Unprotect(request.OrderRef);
73-
var uiOptions = ResolveProtectedUiOptions(request.UiOptions);
72+
var uiOptions = ResolveProtectedUiOptions();
7473

7574
BankIdFlowCollectResult result;
7675
try
@@ -92,8 +91,6 @@ public async Task<ActionResult> Status(BankIdUiApiStatusRequest request)
9291
case BankIdFlowCollectResultComplete complete:
9392
{
9493
var uiResult = ConstructProtectedUiResult(orderRef.OrderRef, complete.CompletionData);
95-
UiOptionsCookieManager.Delete(request.UiOptions);
96-
9794
return OkJsonResult(BankIdUiApiStatusResponse.Finished(request.ReturnUrl, uiResult));
9895
}
9996
case BankIdFlowCollectResultRetry retry:
@@ -102,8 +99,6 @@ public async Task<ActionResult> Status(BankIdUiApiStatusRequest request)
10299
}
103100
case BankIdFlowCollectResultFailure failure:
104101
{
105-
UiOptionsCookieManager.Delete(request.UiOptions);
106-
107102
return BadRequestJsonResult(new BankIdUiApiErrorResponse(failure.StatusMessage));
108103
}
109104
default:
@@ -130,10 +125,9 @@ public ActionResult QrCode(BankIdUiApiQrCodeRequest request)
130125
public async Task<ActionResult> Cancel(BankIdUiApiCancelRequest request)
131126
{
132127
Validators.ThrowIfNullOrWhitespace(request.OrderRef, nameof(request.OrderRef));
133-
Validators.ThrowIfNullOrWhitespace(request.UiOptions, nameof(request.UiOptions));
134128

135129
var orderRef = OrderRefProtector.Unprotect(request.OrderRef);
136-
var uiOptions = ResolveProtectedUiOptions(request.UiOptions);
130+
var uiOptions = ResolveProtectedUiOptions();
137131

138132
await BankIdFlowService.Cancel(orderRef.OrderRef, uiOptions.ToBankIdFlowOptions());
139133

@@ -189,11 +183,10 @@ protected static ActionResult BadRequestJsonResult(object model)
189183
}
190184

191185
/// <summary>
192-
/// Resolves the UiOptions from either a GUID (stored in cookie) or the direct protected value.
186+
/// Resolves the UiOptions stored in cookie and unprotects value.
193187
/// </summary>
194-
protected BankIdUiOptions ResolveProtectedUiOptions(string protectedUiOptionsOrGuid)
188+
protected BankIdUiOptions ResolveProtectedUiOptions()
195189
{
196-
return UiOptionsCookieManager.Retrieve(protectedUiOptionsOrGuid)
197-
?? throw new InvalidOperationException(BankIdConstants.ErrorMessages.InvalidUiOptions);
190+
return UiOptionsCookieManager.Retrieve() ?? throw new InvalidOperationException(BankIdConstants.ErrorMessages.InvalidUiOptions);
198191
}
199192
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,15 @@ public BankIdUiAuthApiController(
3838
public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankIdUiApiInitializeRequest request)
3939
{
4040
Validators.ThrowIfNullOrWhitespace(request.ReturnUrl, nameof(request.ReturnUrl));
41-
Validators.ThrowIfNullOrWhitespace(request.UiOptions, nameof(request.UiOptions));
4241

43-
var uiOptions = ResolveProtectedUiOptions(request.UiOptions);
42+
var uiOptions = ResolveProtectedUiOptions();
4443

4544
BankIdFlowInitializeResult bankIdFlowInitializeResult;
4645
try
4746
{
4847
var returnRedirectUrl = Url.Action(BankIdConstants.Routes.BankIdAuthInitActionName, BankIdConstants.Routes.BankIdAuthControllerName, new
4948
{
50-
returnUrl = request.ReturnUrl,
51-
uiOptions = request.UiOptions
49+
returnUrl = request.ReturnUrl
5250
}, protocol: Request.Scheme) ?? throw new Exception(BankIdConstants.ErrorMessages.CouldNotGetUrlFor(BankIdConstants.Routes.BankIdAuthControllerName, BankIdConstants.Routes.BankIdAuthInitActionName));
5351

5452
bankIdFlowInitializeResult = await BankIdFlowService.InitializeAuth(uiOptions.ToBankIdFlowOptions(), returnRedirectUrl);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ IBankIdUiOptionsCookieManager uiOptionsCookieManager
3131

3232
[HttpGet]
3333
[Route($"/[area]/{BankIdConstants.Routes.BankIdPathName}/{BankIdConstants.Routes.BankIdAuthControllerPath}")]
34-
public Task<ActionResult> Init(string returnUrl, [FromQuery(Name = BankIdConstants.QueryStringParameters.UiOptions)] string uiOptionsGuid)
34+
public Task<ActionResult> Init(string returnUrl)
3535
{
36-
return Initialize(returnUrl, BankIdConstants.Routes.BankIdAuthApiControllerName, uiOptionsGuid, "Init");
36+
return Initialize(returnUrl, BankIdConstants.Routes.BankIdAuthApiControllerName, "Init");
3737
}
3838
}

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,20 @@ protected BankIdUiControllerBase(
4444
_uiOptionsCookieManager = uiOptionsCookieManager;
4545
}
4646

47-
protected async Task<ActionResult> Initialize(string returnUrl, string apiControllerName, string uiOptionsGuid, string viewName)
47+
protected async Task<ActionResult> Initialize(string returnUrl, string apiControllerName, string viewName)
4848
{
4949
Validators.ThrowIfNullOrWhitespace(returnUrl);
50-
Validators.ThrowIfNullOrWhitespace(uiOptionsGuid, BankIdConstants.QueryStringParameters.UiOptions);
5150

5251
if (!Url.IsLocalUrl(returnUrl))
5352
{
5453
throw new ArgumentException(BankIdConstants.ErrorMessages.InvalidReturnUrl);
5554
}
5655

57-
var uiOptions = _uiOptionsCookieManager.Retrieve(uiOptionsGuid) ?? throw new InvalidOperationException(BankIdConstants.ErrorMessages.InvalidUiOptions);
58-
if (!HasStateCookie(uiOptions))
56+
var uiOptions = _uiOptionsCookieManager.Retrieve();
57+
if (uiOptions == null || !HasStateCookie(uiOptions))
5958
{
60-
var invalidStateContext = new BankIdInvalidStateContext(uiOptions.CancelReturnUrl);
59+
var cancelReturnUrl = uiOptions?.CancelReturnUrl ?? "/";
60+
var invalidStateContext = new BankIdInvalidStateContext(cancelReturnUrl);
6161
await _bankIdInvalidStateHandler.HandleAsync(invalidStateContext);
6262

6363
return new EmptyResult();
@@ -75,7 +75,7 @@ protected async Task<ActionResult> Initialize(string returnUrl, string apiContro
7575
}
7676
var state = _bankIdUiStateProtector.Unprotect(protectedState);
7777

78-
var viewModel = GetUiViewModel(returnUrl, apiControllerName, uiOptionsGuid, uiOptions, state, antiforgeryTokens);
78+
var viewModel = GetUiViewModel(returnUrl, apiControllerName, uiOptions, state, antiforgeryTokens);
7979

8080
return View(viewName, viewModel);
8181
}
@@ -91,7 +91,7 @@ private bool HasStateCookie(BankIdUiOptions uiOptions)
9191
return !string.IsNullOrEmpty(HttpContext.Request.Cookies[uiOptions.StateCookieName]);
9292
}
9393

94-
private BankIdUiViewModel GetUiViewModel(string returnUrl, string apiControllerName, string uiOptionsGuid, BankIdUiOptions unprotectedUiOptions, BankIdUiState uiState, AntiforgeryTokenSet antiforgeryTokens)
94+
private BankIdUiViewModel GetUiViewModel(string returnUrl, string apiControllerName, BankIdUiOptions unprotectedUiOptions, BankIdUiState uiState, AntiforgeryTokenSet antiforgeryTokens)
9595
{
9696
Validators.ThrowIfNullOrWhitespace(antiforgeryTokens.RequestToken, nameof(antiforgeryTokens.RequestToken));
9797

@@ -119,8 +119,6 @@ private BankIdUiViewModel GetUiViewModel(string returnUrl, string apiControllerN
119119

120120
ReturnUrl = returnUrl,
121121
CancelReturnUrl = Url.Content(unprotectedUiOptions.CancelReturnUrl),
122-
123-
UiOptionsGuid = uiOptionsGuid
124122
};
125123

126124
var localizedStartAppButtonText = _localizer["StartApp_Button"];

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ public BankIdUiPaymentApiController(
4444
public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankIdUiApiInitializeRequest request)
4545
{
4646
Validators.ThrowIfNullOrWhitespace(request.ReturnUrl, nameof(request.ReturnUrl));
47-
Validators.ThrowIfNullOrWhitespace(request.UiOptions, nameof(request.UiOptions));
4847

49-
var uiOptions = ResolveProtectedUiOptions(request.UiOptions);
48+
var uiOptions = ResolveProtectedUiOptions();
5049

5150
var state = GetStateFromCookie(uiOptions);
5251
if(state == null)
@@ -59,8 +58,7 @@ public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankId
5958
{
6059
var returnRedirectUrl = Url.Action(BankIdConstants.Routes.BankIdPaymentInitActionName, BankIdConstants.Routes.BankIdPaymentControllerName, new
6160
{
62-
returnUrl = request.ReturnUrl,
63-
uiOptions = request.UiOptions
61+
returnUrl = request.ReturnUrl
6462
}, protocol: Request.Scheme) ?? throw new Exception(BankIdConstants.ErrorMessages.CouldNotGetUrlFor(BankIdConstants.Routes.BankIdPaymentControllerName, BankIdConstants.Routes.BankIdPaymentInitActionName));
6563

6664
bankIdFlowInitializeResult = await BankIdFlowService.InitializePayment(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ IBankIdUiOptionsCookieManager uiOptionsCookieManager
3232
[HttpGet]
3333
[AllowAnonymous]
3434
[Route($"/[area]/{BankIdConstants.Routes.BankIdPathName}/{BankIdConstants.Routes.BankIdPaymentControllerPath}")]
35-
public Task<ActionResult> Init(string returnUrl, [FromQuery(Name = BankIdConstants.QueryStringParameters.UiOptions)] string protectedUiOptions)
35+
public Task<ActionResult> Init(string returnUrl)
3636
{
37-
return Initialize(returnUrl, BankIdConstants.Routes.BankIdPaymentApiControllerName, protectedUiOptions, "Init");
37+
return Initialize(returnUrl, BankIdConstants.Routes.BankIdPaymentApiControllerName, "Init");
3838
}
3939
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,11 @@ public BankIdUiSignApiController(
4444
public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankIdUiApiInitializeRequest request)
4545
{
4646
Validators.ThrowIfNullOrWhitespace(request.ReturnUrl, nameof(request.ReturnUrl));
47-
Validators.ThrowIfNullOrWhitespace(request.UiOptions, nameof(request.UiOptions));
4847

49-
var uiOptions = ResolveProtectedUiOptions(request.UiOptions);
48+
var uiOptions = ResolveProtectedUiOptions();
5049

5150
var state = GetStateFromCookie(uiOptions);
52-
if(state == null)
51+
if (state == null)
5352
{
5453
throw new InvalidOperationException(BankIdConstants.ErrorMessages.InvalidStateCookie);
5554
}
@@ -59,8 +58,7 @@ public async Task<ActionResult<BankIdUiApiInitializeResponse>> Initialize(BankId
5958
{
6059
var returnRedirectUrl = Url.Action(BankIdConstants.Routes.BankIdSignInitActionName, BankIdConstants.Routes.BankIdSignControllerName, new
6160
{
62-
returnUrl = request.ReturnUrl,
63-
uiOptions = request.UiOptions
61+
returnUrl = request.ReturnUrl
6462
}, protocol: Request.Scheme) ?? throw new Exception(BankIdConstants.ErrorMessages.CouldNotGetUrlFor(BankIdConstants.Routes.BankIdSignControllerName, BankIdConstants.Routes.BankIdSignInitActionName));
6563

6664
bankIdFlowInitializeResult = await BankIdFlowService.InitializeSign(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ IBankIdUiOptionsCookieManager uiOptionsCookieManager
3232
[HttpGet]
3333
[AllowAnonymous]
3434
[Route($"/[area]/{BankIdConstants.Routes.BankIdPathName}/{BankIdConstants.Routes.BankIdSignControllerPath}")]
35-
public Task<ActionResult> Init(string returnUrl, [FromQuery(Name = BankIdConstants.QueryStringParameters.UiOptions)] string protectedUiOptions)
35+
public Task<ActionResult> Init(string returnUrl)
3636
{
37-
return Initialize(returnUrl, BankIdConstants.Routes.BankIdSignApiControllerName, protectedUiOptions, "Init");
37+
return Initialize(returnUrl, BankIdConstants.Routes.BankIdSignApiControllerName, "Init");
3838
}
3939
}

src/ActiveLogin.Authentication.BankId.AspNetCore/Areas/ActiveLogin/Models/BankIdUiApiCancelRequest.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ public BankIdUiApiCancelRequest()
99

1010
}
1111

12-
[Required]
13-
public string? UiOptions { get; set; }
14-
1512
[Required]
1613
public string? OrderRef { get; set; }
1714
}

src/ActiveLogin.Authentication.BankId.AspNetCore/Areas/ActiveLogin/Models/BankIdUiApiInitializeRequest.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,4 @@ public BankIdUiApiInitializeRequest()
1010

1111
[Required]
1212
public string? ReturnUrl { get; set; }
13-
14-
[Required]
15-
public string? UiOptions { get; set; }
1613
}

0 commit comments

Comments
 (0)