Closed dionrhys closed 1 year ago
@dionrhys Thanks for this! If you want to add tests I'm totally game to review, but appreciate the manual bits here and wanted to unblock ASAP as well.
Np and thank you! I had a look at adding tests for OIDC state reading and writing specifically but it's quite a shallow part of the logic here that I wasn't sure adding the complexity of extracting these out was worth the effort. Adding tests for the controller actions as a whole seemed like quite a bit of work as well.
This PR fixes an issue with
AuthController.RedirectToProvider
not encodingid
andreturnUrl
values within the OIDCstate
parameter, leading the server to redirect to the wrong URL after login in some cases.The
state
parameter is expected to decode as if it was a query string, but the values within the parameter weren't being encoded as query string values, so the decoding was lossy and would not round-trip the return URL if that URL contained more than one query parameter (e.g. for an exception detail URL:/exceptions/detail?id=...&log=...&store=...
).Steps to reproduce:
https://opserver.example.com/exceptions/detail?id=00000000-0000-0000-0000-000000000000&log=Core&store=Example+%3A+Production
) while not logged inBefore this PR, Opserver will redirect you to
https://opserver.example.com/exceptions/detail?id=00000000-0000-0000-0000-000000000000
after logging in (missing thelog
andstore
query parameters in the URL), so you'll get the "Error was not found. If this link worked previously, the error was hard deleted." page.After this PR, Opserver should redirect you to
https://opserver.example.com/exceptions/detail?id=00000000-0000-0000-0000-000000000000&log=Core&store=Example+%3A+Production
as expected.Let me know if you'd prefer the OIDC
state
parameter encoding/decoding to have unit tests, or any other feedback or desired changes!LINQPad script to compare before and after code:
```csharp void Main() { "Before PR Auth URL:".Dump(); var beforePRAuthUrl = BeforePR_GetAuthUrl(); beforePRAuthUrl.Dump(); DecodeStateFromAuthUrl(beforePRAuthUrl).Dump(); "After PR Auth URL:".Dump(); var afterPRAuthUrl = AfterPR_GetAuthUrl(); afterPRAuthUrl.Dump(); DecodeStateFromAuthUrl(afterPRAuthUrl).Dump(); } DictionaryResult: