you don't appear to coded the flow correctly
- the blazor app will redirect to the auth server passing a reply url (redirect_uri), scope, state and code challenge. the reply url is typically the client action that process the client authentication. in your code this is /authorize
- the auth server validates the reply url, and displays a login page. you server redirects
- the user fills in the login page and posts
- on post if valid, the auth server redirects back to the passed reply url with a code
- the client site uses the code to call back to the auth site to get the user credentials
- if valid the client site creates a cookie and redirect to the client page that needed authentication. typically this information is passed as a query string on the reply url sent in step 1.
your /authorize action has several issues.
- you are creating the code and passing in the return url. but the code is a key to the login. your ValidateAuthorizationCode() is supported to convert the code to a user, when the client calls /TokenExchange with the code. but your code doesn't update the dictionary
- after login you are supposed to return to the reply url passing the code. your code doesn't do this.
as you are using razor page login, you probably want a new connection action that does this. it should require authorization and will use the httpcontext user (set by the razor login page). to get user information. if the action is called /authorize/postlogin then the return url would be something like:
var returnUrl = $"/authorize/postlogin?state={state}&redirect_uri={redirect_uri}";
var loginUrl = $"https://localhost:7098/account/login?returnurl={WebUtility.UrlEncode(returnUrl)}";
then in the /authorize/postlogin action, you would generate the code and redirect to back to the client:
[HttpGet("authorize/postlogin")]
public async Task<IActionResult> PostLogin(
[FromQuery] string redirect_uri,
[FromQuery] string state,
[FromQuery] string code_challenge,
[FromQuery] string code_challenge_method)
{
// create code from user & code_challenge and store for later TokenExchange call
var code = ....;
return Redirect($"{redirect_uri}{redirect_uri.Contains('?') ? "&" : "?"}code={code}&state={state}";
}
the client would then call /TokenExchange with the code and the verification for the stored code_challenge.