C
C#3mo ago
Swyftey

✅ Discord Authentication Redirection Issue

Hi. I am new to C#/ASP.NET and just want this Discord OAuth "Challenge" to work properly. Current Routes: - "/auth/login" - "auth/login-redirect" The issue is: When I click "Authorize" on the Discord page and it's supposed to redirect me to my desired callback URL, it just hits the login route ("/auth/login") again. The redirect URL IS apparently hit, but nothing is executed like it should be. EDIT: If I set the "RedirectUri" to "RedirectLogin", the code and state query parameters are not passed through. Any help is greatly appreciated, thanks!
No description
No description
No description
21 Replies
Swyftey
SwyfteyOP3mo ago
I feel I'm getting closer and closer to a fix, I think just an example on how this code should look would be really helpful, thanks! bump
arion
arion3mo ago
There seems to be some of your OAuth configurations that you may be missing on your authentication scheme. Could you show how your middleware is set up per chance? (Make sure to redact / blur any secrets if hardcoded) I've set up a video of how I created a similar controller as in your screenshots
Swyftey
SwyfteyOP3mo ago
Hi. Sorry for the late reply! I am currently not at my computer, but the middleware setup is close to the default setup Visual Studio provides. I’ll send a screenshot when I can.
arion
arion3mo ago
Sorry, I mispoke there. I meant OAuth Handler
Swyftey
SwyfteyOP3mo ago
Sorry, I’m really new to C#/asp.net, I don’t think I have an OAuth handler currently.
arion
arion3mo ago
You can use a nuget package like Discord.OAuth2 but the code for it is rather simple, you could read through whats being done and implement it yourself if you want. Then you can just do something like this in your service collection
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "Discord";
})
.AddDiscord(options =>
{
options.AppId = "CLIENT ID";
options.AppSecret = "CLIENT SECRET";
options.Scope.Add("email"); // example scope 1
options.Scope.Add("guilds"); // example scope 2
})
.AddCookie();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "Discord";
})
.AddDiscord(options =>
{
options.AppId = "CLIENT ID";
options.AppSecret = "CLIENT SECRET";
options.Scope.Add("email"); // example scope 1
options.Scope.Add("guilds"); // example scope 2
})
.AddCookie();
Do note that if you use the nuget package, it does create a /signin-discord endpoint which needs to be whitelisted on the discord portal under redirects eg.
Swyftey
SwyfteyOP3mo ago
Thank you for this! Out of curiosity, what is the difference between the package you sent and the package I am currently using (AspNet.Security.OAuth.Discord)? I'm afraid that if I use the package you sent, it will possibly be the same issue. This is what I currently have:
c#
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "Discord";
})
.AddCookie()
.AddDiscord(options =>
{
options.ClientId = builder.Configuration["BotConfiguration:ClientId"];

options.ClientSecret = builder.Configuration["BotConfiguration:ClientSecret"];

options.CallbackPath = "/auth/login-redirect";
options.AuthorizationEndpoint = "https://discord.com/api/oauth2/authorize";

options.TokenEndpoint = "https://discord.com/api/oauth2/token";

options.UserInformationEndpoint = "https://discord.com/api/v10/users/@me";

options.Scope.Add("identify");
options.SaveTokens = true;
});
c#
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "Discord";
})
.AddCookie()
.AddDiscord(options =>
{
options.ClientId = builder.Configuration["BotConfiguration:ClientId"];

options.ClientSecret = builder.Configuration["BotConfiguration:ClientSecret"];

options.CallbackPath = "/auth/login-redirect";
options.AuthorizationEndpoint = "https://discord.com/api/oauth2/authorize";

options.TokenEndpoint = "https://discord.com/api/oauth2/token";

options.UserInformationEndpoint = "https://discord.com/api/v10/users/@me";

options.Scope.Add("identify");
options.SaveTokens = true;
});
OK. From what I am maybe starting to understand: Do I not need a specific endpoint for the callback url (e.g, "/login-redirect")? I thought I specifically needed to authorize the user (based on the code and state returned), but maybe the oauth package does that for you already? This was my issue as far as I am aware. I shouldn't have made my own endpoint for the callback URL ("/login-redirect"), it should just be a function/task whatever tf it's considered in c# 😭 . Thanks for the help
arion
arion3mo ago
:ThumbsUp: All the "Magic" happens within the DiscordHandler.cs CreateTicketAsync for the OAuth2 $close
MODiX
MODiX3mo ago
If you have no further questions, please use /close to mark the forum thread as answered
arion
arion3mo ago
This is some info the response in that method
{
"id": "155396491853168640",
"username": "_arion",
"avatar": "ef602edb7a613a05c2293ab3fe1f2876",
"discriminator": "0",
"public_flags": 4194432,
"flags": 4194432,
"banner": "a_56bfe3dfae7d79349b8ad01e3a67ec5a",
"accent_color": 0,
"global_name": "arion",
"avatar_decoration_data": null,
"banner_color": "#000000",
"clan": null,
"mfa_enabled": true,
"locale": "en-GB",
"premium_type": 2,
"email": "[email protected]",
"verified": true
}
{
"id": "155396491853168640",
"username": "_arion",
"avatar": "ef602edb7a613a05c2293ab3fe1f2876",
"discriminator": "0",
"public_flags": 4194432,
"flags": 4194432,
"banner": "a_56bfe3dfae7d79349b8ad01e3a67ec5a",
"accent_color": 0,
"global_name": "arion",
"avatar_decoration_data": null,
"banner_color": "#000000",
"clan": null,
"mfa_enabled": true,
"locale": "en-GB",
"premium_type": 2,
"email": "[email protected]",
"verified": true
}
The only thing thats sensitive info (or may be regarded as such) is email
Swyftey
SwyfteyOP3mo ago
Yeah If all that happens within the handler, do I need to call this still?
c#

[ApiExplorerSettings(IgnoreApi = true)]
public async Task<IActionResult> LoginRedirect()
{
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
if (!result.Succeeded)
{
return Unauthorized();
}
Console.WriteLine("OK");
return Ok();
}
c#

[ApiExplorerSettings(IgnoreApi = true)]
public async Task<IActionResult> LoginRedirect()
{
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
if (!result.Succeeded)
{
return Unauthorized();
}
Console.WriteLine("OK");
return Ok();
}
arion
arion3mo ago
I'd probably edit the implementation of the nuget package if I were you. People dislike seeing their usernames as logins. You can add the "global_name" to that and it will add it under claims https://github.com/lukepfeiffer10/Discord.OAuth2/blob/master/src/Discord.OAuth2/DiscordOptions.cs#L23
Swyftey
SwyfteyOP3mo ago
Username as in "display name"?
arion
arion3mo ago
The login redirect is the web page that discord will redirect the user to after they've authenticated my username is _arion my display name is arion
Swyftey
SwyfteyOP3mo ago
gotcha Yes, but that's what "LoginRedirect" was, just with an endpoint, but it was never firing as an endpoint, it works without the endpoint/route assigned to it omg nvm
arion
arion3mo ago
The redirect page is the page the user needs to goto after being "Signed in"
Swyftey
SwyfteyOP3mo ago
It's confusing coming from JavaScript I think In javascript, I basically just made an endpoint called "login-redirect" which is what discord's redirect_uri was set to, and it would execute in this scenerio, it doesn't, but calling it as a function (instead of making it an endpoint) which then redirects to a url path works
arion
arion3mo ago
Try playing around with everything, the debugger is your friend, you can see the request headers, claims and everything during debugging just stick a break point and it can tell you much about the current request I believe the Authorization middleware is triggered first though, incase u wanna debug that too
Swyftey
SwyfteyOP3mo ago
Thank you!
Want results from more Discord servers?
Add your server