I'm trying to create an external login scheme for facebook, google and linkedin without using identity framework. I have an api that stores all users and do some authentication stuffs. Right now I'm kind of lost on how to get the information from the external login.
I'm issuing a challenge like this.
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult ExternalLogin(string provider)
{
//Issue a challenge to external login middleware to trigger sign in process
return new ChallengeResult(provider);
}
This works well, it redirects me to either google, facebook or linkedinn authentication.
Now on this part:
public async Task<IActionResult> ExternalLoginCallback()
{
//Extract info from externa; login
return Redirect("/");
}
All I want is to get the information that was provided by the external login.
I have tried what I found from my research,
var result = await HttpContext.AuthenticateAsync(provider);
if (result?.Succeeded != true)
{
return Redirect("/");
}
var externalUser = result.Principal;
var claims = externalUser.Claims.ToList();
First of all I I'm not sure if a simple ?provider=Google
on my callback string will pass the provider name I specify so it can be used to check the sign in scheme. I guess this is incorrect. Secondly, I tried hard coding await HttpContext.AuthenticateAsync("Google")
and when it reach this code, the debug stops. I'm not sure why.
I've seen the generated code when creating a project with single authentication.
var info = await _signInManager.GetExternalLoginInfoAsync();
Sadly, I'm won't be able to use identity since I don't have a user store and my application will be consuming an API.
First you need to create a custom cookie handler. I myself had problems with:
No IAuthenticationSignInHandler is configured to handle sign in for the scheme: Bearer
I had to add a cookie handler that will temporarily store the outcome of the external authentication, e.g. the claims that got sent by the external provider. This is necessary, since there are typically a couple of redirects involved until you are done with the external authentication process.
Startup
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
{
o.TokenValidationParameters = tokenValidationParameters;
})
.AddCookie("YourCustomScheme")
.AddGoogle(googleOptions =>
{
googleOptions.SignInScheme = "YourCustomScheme";
googleOptions.ClientId = "x";//Configuration["Authentication:Google:ClientId"];
googleOptions.ClientSecret = "x";//Configuration["Authentication:Google:ClientSecret"];
//googleOptions.CallbackPath = "/api/authentication/externalauthentication/signin-google";
});
The important part here is "YourCustomScheme".
Now it's time to retrieve the user information from the claims provided by the external authentication in the callback action.
Controller
[AllowAnonymous]
[HttpPost(nameof(ExternalLogin))]
public IActionResult ExternalLogin(ExternalLoginModel model)
{
if (model == null || !ModelState.IsValid)
{
return null;
}
var properties = new AuthenticationProperties { RedirectUri = _authenticationAppSettings.External.RedirectUri };
return Challenge(properties, model.Provider);
}
[AllowAnonymous]
[HttpGet(nameof(ExternalLoginCallback))]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
//Here we can retrieve the claims
var result = await HttpContext.AuthenticateAsync("YourCustomScheme");
return null;
}
Voilà! We now have some user information to work with!
Helpful link
http://docs.identityserver.io/en/release/topics/signin_external_providers.html
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments