Hi,@Andrew White
Since you are also using the scheme IdentityConstants.ApplicationScheme
wthich is based on cookie protecting your Blazor app
builder.Services .AddAuthentication(options => { options.DefaultScheme = IdentityConstants.ApplicationScheme; }) .AddIdentityCookies();
In your scenario, you could send request to login endpoint with query parameter useCookies=true
,
then the cookie would be generated in response
The source codes of login endpoint:
routeGroup.MapPost("/login", async Task<Results<Ok<AccessTokenResponse>, EmptyHttpResult, ProblemHttpResult>>
([FromBody] LoginRequest login, [FromQuery] bool? useCookies, [FromQuery] bool? useSessionCookies, [FromServices] IServiceProvider sp) =>
{
var signInManager = sp.GetRequiredService<SignInManager<TUser>>();
var useCookieScheme = (useCookies == true) || (useSessionCookies == true);
var isPersistent = (useCookies == true) && (useSessionCookies != true);
signInManager.AuthenticationScheme = useCookieScheme ? IdentityConstants.ApplicationScheme : IdentityConstants.BearerScheme;
var result = await signInManager.PasswordSignInAsync(login.Email, login.Password, isPersistent, lockoutOnFailure: true);
if (result.RequiresTwoFactor)
{
if (!string.IsNullOrEmpty(login.TwoFactorCode))
{
result = await signInManager.TwoFactorAuthenticatorSignInAsync(login.TwoFactorCode, isPersistent, rememberClient: isPersistent);
}
else if (!string.IsNullOrEmpty(login.TwoFactorRecoveryCode))
{
result = await signInManager.TwoFactorRecoveryCodeSignInAsync(login.TwoFactorRecoveryCode);
}
}
if (!result.Succeeded)
{
return TypedResults.Problem(result.ToString(), statusCode: StatusCodes.Status401Unauthorized);
}
// The signInManager already produced the needed response in the form of a cookie or bearer token.
return TypedResults.Empty;
});
The codes to read the cookie and append it to response in static server render mode:
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
var client = new HttpClient(handler);
var response = await client.PostAsJsonAsync("{BaseUrl}/login?useCookies=true", Input);
if(response.StatusCode == HttpStatusCode.OK)
{
var respCookies = cookies.GetCookies(new Uri("{BaseUrL}"));
var authCookie = respCookies.Where(x => x.Name == ".AspNetCore.Identity.Application").FirstOrDefault();
if (authCookie != null)
{
HttpContext.Response.Cookies.Delete(".AspNetCore.Identity.Application");
HttpContext.Response.Cookies.Append(".AspNetCore.Identity.Application", authCookie.Value, new CookieOptions()
{
Domain = authCookie.Domain,
HttpOnly = authCookie.HttpOnly,
SameSite = SameSiteMode.None,
Path = authCookie.Path,
Secure = authCookie.Secure,
Expires = authCookie.Expires,
});
}
RedirectManager.RedirectTo(ReturnUrl);
}
In interactive render mode,you could set the cookie with js codes
and share the cookie between two apps by register the service in both projects:
builder.Services.AddDataProtection()
.SetApplicationName("SameAppName");
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards, Ruikai Feng