[SOLVED] ASP.NET – Problem with authentication: Manually added claim is missing in the next request

Issue

I am currently experimenting with external login providers like Google Authentication in my ASP.NET application.

As you can see on my Program.cs i’am running .NET6.

After the Google-Login was successfull, the ClaimsPrincipal has exactly one ClaimsIdentity (IsAuthenticated == true). Now I want to add my own ‘Custom-Claim’ to this identity. The addition works without any problems, but the next request is missing the custom claim (all other claims by Google are there).

Here is the part of my Program.cs where I add the authentication:

builder.Services.AddAuthentication(x =>
{
    x.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogle(GoogleDefaults.AuthenticationScheme, o =>
{
    o.ClientId = builder.Configuration["Authentication:Google:ClientId"];
    o.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];   
    o.ClaimActions.MapJsonKey("urn:google:picture","picture","url");
});

Here is the configuration of the middleware pipeline in Program.cs:

app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();

app.Use((httpContext, func) =>
{
    if (httpContext.Request.Path.StartsWithSegments("/api"))
        httpContext.Request.Headers[HeaderNames.XRequestedWith] = "XMLHttpRequest";

    return func();
});

app.UseRouting();
app.MapRazorPages();
app.MapControllers();

Endpoint for Google Login:

[HttpGet]
[Route("GoogleSignIn")]
public async Task GoogleSignIn()
{
    await HttpContext.ChallengeAsync(GoogleDefaults.AuthenticationScheme,
        new AuthenticationProperties {RedirectUri =Url.Action("GoogleResponse")});
}

In the "GoogleResponse" method i add the mentioned custom claim:

//this method gets called after the google login has finished
public async Task<IActionResult> GoogleResponse()
{
    var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    
    var identity = result.Principal.Identities.FirstOrDefault();
    var currentSidClaim = identity.FindFirst(x => x.Type == ClaimTypes.Sid);

    if (currentSidClaim != null)
        identity.RemoveClaim(currentSidClaim);
    
    identity.AddClaim(new Claim(ClaimTypes.Sid, "Hi i am some claim, but i'll miss on the next request :("));
   
    return Redirect("/");
}

ClaimsIdentity after adding the claim:

[https://i.stack.imgur.com/INdGy.png]

ClaimsIdentity on the next request (in the same controller btw):

[https://i.stack.imgur.com/oft3e.png]

Whether I access the identity via "User.Identity" or "HttpContext.User…" makes no difference.

Really hope somebody can clear things up for me.

I hope I don’t have to implement a large / elaborate ASP.NET Identity solution to solve the problem. I would be happy with a lightweight authentication.

UPDATE:

After some further tests it looks like it is not necessarily related to the specific Google login. Even if I create a second identity at login, it is gone at the next request.

I guess the authentication cookie is not updated.

Thanks in advance!

Solution

Try to add claims after callback from the external website. As described here

Answered By – Serhii

Answer Checked By – Cary Denson (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *