Identity Server 6 Invalid redirect Uri with WinForms client

208 views Asked by At

Trying to build an interactive login form in a NET 6 WinForms app, using Identity Server 6 but heavily inspired on the Winforms client example provided here: https://github.com/IdentityModel/IdentityModel.OidcClient.Samples/tree/main/WinFormsWebView2/WinFormsWebView2

Getting this error rendered in the client-side 'browser':

Sorry, there was an error : invalid_request Invalid redirect_uri

On the local console of the IS6 project, it shows this error:

[23:04:00 Error] Duende.IdentityServer.Validation.AuthorizeRequestValidator Invalid redirect_uri: http://localhost/winforms.client

{
    "ClientId": "vr2-win-client",
    "ClientName": null,
    "RedirectUri": null,
    "AllowedRedirectUris": [],
    "SubjectId": "anonymous",
    "ResponseType": null,
    "ResponseMode": null,
    "GrantType": null,
    "RequestedScopes": "",
    "State": null,
    "UiLocales": null,
    "Nonce": null,
    "AuthenticationContextReferenceClasses": null,
    "DisplayMode": null,
    "PromptMode": "",
    "MaxAge": null,
    "LoginHint": null,
    "SessionId": null,
    "Raw": {
       "response_type"        : "code",
       "state"                : "IdqJr9LGl9n_0lcl0LlTVA",
       "code_challenge"       : "v7Bjclv_Ivn7Kltp-7iCOCqdUZxJIxVSf27Ecau2G2o",
       "code_challenge_method": "S256",
       "client_id"            : "vr2-win-client",
       "scope"                : "vr2-client-api offline_access openid",
       "redirect_uri"         : "http://localhost/winforms.client"
    }
},
"$type": "AuthorizeRequestValidationLog"
}

[23:04:00 Error] Duende.IdentityServer.Endpoints.AuthorizeEndpoint Request validation failed

I can't figure out why, since the specified Redirect URIs do exactly match. [Incidentally, for a quick moan: this identity server business is bafflingly difficult to get right and hard to work with. I've been at at this for weeks now, and all i want to do to is to protect one api on the backend and provision an interactive login at the frontend; there Must be an Easier Way]

This is the code in my IS client config:

public static IEnumerable<Client> Clients =>
        new List<Client>
        {
            new Client
            {
                ClientId = "vr2-win-client",
             
                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile
                },

                RequireClientSecret = false,
                AllowedGrantTypes = GrantTypes.Code,
                RequirePkce = true,
                RedirectUris = { "https://notused", "http://localhost/winforms.client" },
                PostLogoutRedirectUris = { "https://notused" },
                AllowOfflineAccess = true,
                RequireConsent = false

                // scopes that client has access to
                //AllowedScopes = { "vr2-client-api" }
            }
        };

And on the client side code I have this:

private async void LoginBtn_Click(object sender, EventArgs e)
        {
            var oidcOptions = new OidcClientOptions
            {
                Authority = config["IdentityServerAddress"].ToString(),
                ClientId = "vr2-win-client",
                Scope = "vr2-client-api offline_access openid",
                RedirectUri = "http://localhost/winforms.client",
                Browser = this.loginWebForm
            };
            
            OidcClient _oidcClient = new OidcClient(oidcOptions);
                        
            LoginResult loginResult = await _oidcClient.LoginAsync();

            if (loginResult.IsError)
            {
                MessageBox.Show(loginResult.Error, "Login", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            this.accessTokenLifetimeManager = new AccessTokenLifetimeManager
                (loginResult, 600, cancellationOnExitTokenSource.Token, config);

            var refreshTokenTask = Task.Run(accessTokenLifetimeManager.PeriodicallyRefreshAccessTokensWorkerTaskAsync);

            vr2Button.Enabled = true;
        } 

I am using IdentityModel.OidcClient v5.2.1 on the client side And Identity Server v6.3.2

I am super grateful for any ideas as to what I've missed or what it is that I am doing wrong here. Presumably there must be an additional validation requirement (for the redirect URL) which the error messages does not describe, any pointers would be much appreciated.

thanks

0

There are 0 answers