I have a Web Api which handles OpenId sign in such way:
[HttpGet]
[AllowAnonymous]
[Route("ExternalLogin", Name = "ExternalLogin")]
public async Task<IActionResult> ExternalLogin(string provider, string returnUrl = "")
{
ApplicationUser user = await GetAuthUser();
string userId = user?.Id;
var properties = _externalSignInService.ConfigureExternalAuthenticationProperties(provider, Url.Action("ExternalCallback", "Account", new { returnUrl, userId }));
return Challenge(properties, provider);
}
This is called from Angular app with JS redirect function (it is hardcoded, because I am trying to make it works firstly).
public loginExternal() {
window.location.href = `https://localhost:5001/v1/account/ExternalLogin?provider=Steam&returnUrl=${window.location.href}`;
}
After Steam login success, it makes to callback method specified there Url.Action(...)
[HttpGet]
[AllowAnonymous]
[Route("Steam", Name = "ExternalCallback")]
public async Task<ActionResult<LoginResponseDto>> ExternalCallback(string error = null, string returnUrl = "", string userId = null)
{
if (error != null)
{
return Redirect(returnUrl + "/unauthorized");
}
...sign in duties...
return ProduceLoginResponse(signInResult);
}
private ActionResult<LoginResponseDto> ProduceLoginResponse((AppSignInResult result, SignInData data) loginResults)
{
var (result, data) = loginResults;
return result switch
{
AppSignInResult.Success => Ok(new LoginResponseDto()
{
AccessToken = data.Token.AccessToken,
TokenType = data.Token.TokenType,
ExpiresIn = data.Token.GetRemainingLifetimeSeconds(),
Username = data.Username,
Email = data.Email,
IsExternalLogin = data.IsExternalLogin,
ExternalAuthenticationProvider = data.ExternalAuthenticationProvider
}),
_ => throw new InvalidEnumArgumentException($"Unknown sign-in result '{result}'.")
};
}
So in my Angular app I need to process this data (save JWT token in storage, etc..). How to do it keeping in mind that I used window.location.href
redirect?
I've figured it out with saving user sign in data in HttpContext.Session
storage and changing return approach from return ProduceLoginResponse(signInResult);
to return Redirect(returnHost + "/sign-in");
and after redirect, in angular SignIn component inside ngOnInit
method I am calling another endpoint to get my sign in data from HttpContext.Session
storage.
[HttpGet]
[AllowAnonymous]
[Route("sign-in")]
public ActionResult<object> ProvideSignInDataFromSession()
{
var sessionData = HttpContext.Session.GetString(SignInDataKey);
if (sessionData != null)
{
var data = JsonConvert.DeserializeObject<SignInData>(sessionData);
return Ok(new
{
user = data.Username,
access_token = data.Token.AccessToken,
token_type = data.Token.TokenType,
expires_in = data.Token.GetRemainingLifetimeSeconds(),
});
}
return Redirect(CORS.CORS.returnOrigin + "/unauthorized");
}