Search code examples
c#.netoauth-2.0discord

Unable to get authentication code from redirect url when authenticating with OAuth2 from .NET desktop app


I am attempting to create a desktop application in .NET that allows a user to login using OAuth2. However, I'm never able to get the context from the redirect url. When I start the process, I'm able to get to the authentication url, and clicking on the authenticate button sends me to the redirect url with the access token, but I'm unable to use it in my code, which is where it needs to be used. Can someone help me out and tell me what I'm doing wrong here?

public class Authenticate
{
    private Browser _browser;

    public async Task AuthenticateUser()
    {
        _browser = new();

        string redirect = "https://localhost:7270/discord/auth";
        string url = "https://discord.com/oauth2/authorize?response_type=code&client_id={MyClientId}&scope={MyScopes}&redirect_uri={HttpUtility.UrlEncode(redirectUrl)}";

        BrowserOptions options = new(url, "https://localhost:7270/");

        BrowserResult result = await _browser.InvokeAsync(options, default);
    }
}

public class Browser : IBrowser
{
    public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken)
    {
        Process.Start(new ProcessStartInfo(options.StartUrl) { UseShellExecute = true, });

        var result = new BrowserResult();

        using(var listener = new HttpListener())
        {
            var listenUrl = options.EndUrl;

            listener.Prefixes.Add(listenUrl);
            listener.Start();

            try
            {
                var context = await listener.GetContextAsync();

                result.Response = context.Request.Url.AbsoluteUri;

                return result;
            }
            catch(Exception ex)
            {
                return result;
            }
        }
    }
}

What's happening is, it'll run to the line where it attempts to get the listener Context, and just spins. No exceptions are thrown, no break points are hit, nothing is ever returned.

As you can see from the images below, both the authorize and redirect urls are working as expected. However, my code needs the code query parameter from the redirect url, which is what I'm unable to get.

Auth endpoint

Redirect

Thanks in advance


Solution

  • Your code looks basically right except that you should use a plain HTTP URL when listening for a loopback response. It is not practical to set up TLS and manage certificates for this type of connection.

    An intercepted authorization code should be protected by the PKCE mechanism. You ahould update your code to use it if supported by your authorization server. More on these topics in the RFC 8252 document.