I want to get the user for example to be able to register with Steam and be able to link his Discord account.
So far I have managed to get a user to register with Steam (or any provider like Google) but I have not found any documentation on how to link accounts (Google => Discord). So far i have this:
Program.cs
builder.Services.AddAuthentication(opt =>
{
opt.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
opt.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = DiscordAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(opt =>
{
opt.LoginPath = "/signin";
opt.LogoutPath = "/signout";
}
)
.AddDiscord(x =>
{
x.ClientId = builder.Configuration.GetSection("Keys")["ClientID"];
x.ClientSecret = builder.Configuration.GetSection("Keys")["SecretID"];
x.SaveTokens = true;
})
.AddSteam(x =>
{
x.ApplicationKey = builder.Configuration.GetSection("Keys")["SteamID"];
x.SaveTokens = true;
});
AuthController.cs
[HttpPost("~/signin")]
public async Task<IActionResult> SignIn([FromForm] string provider)
{
if (string.IsNullOrWhiteSpace(provider))
{
return BadRequest();
}
if (!await HttpContext.IsProviderSupportedAsync(provider))
{
return BadRequest();
}
// Instruct the middleware corresponding to the requested external identity
// provider to redirect the user agent to its own authorization endpoint.
// Note: the authenticationScheme parameter must match the value configured in Startup.cs
return Challenge(new AuthenticationProperties { RedirectUri = "/" }, provider);
}
[HttpGet("~/signout")]
[HttpPost("~/signout")]
public IActionResult SignOutCurrentUser()
{
// Instruct the cookies middleware to delete the local cookie created
// when the user agent is redirected from the external identity provider
// after a successful authentication flow (e.g Google or Facebook).
return SignOut(new AuthenticationProperties { RedirectUri = "/" },
CookieAuthenticationDefaults.AuthenticationScheme);
}
HttpContextExtensions.cs The functions present in this class is to determine what provider want to use the user and if supported.
public static class HttpContextExtensions
{
public static async Task<AuthenticationScheme[]> GetExternalProvidersAsync(this HttpContext context)
{
ArgumentNullException.ThrowIfNull(context);
var schemes = context.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();
return (from scheme in await schemes.GetAllSchemesAsync()
where !string.IsNullOrEmpty(scheme.DisplayName)
select scheme).ToArray();
}
public static async Task<bool> IsProviderSupportedAsync(this HttpContext context, string provider)
{
ArgumentNullException.ThrowIfNull(context);
return (from scheme in await context.GetExternalProvidersAsync()
where string.Equals(scheme.Name, provider, StringComparison.OrdinalIgnoreCase)
select scheme).Any();
}
}
Finally, for auth i'm using AspNet.Security.OAuth.Discord and AspNet.Security.OpenId.Steam mostly of the code that I show can be found in the sample folder of the github.