C
C#2mo ago
Espionage

✅ Identity Help

I have a React Frontend where I'm doing OAuth with Google, and I wanted to pass along this signin to my aspnetcore backend. I've implemented identity and can see during the login process that my HttpContext.User has been set correctly with its basic claims. In the logs at that time I see this:
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
AuthenticationScheme: Identity.Application signed in.
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
AuthenticationScheme: Identity.Application signed in.
I check my browser, I can see the cookie has been set succesfully, when I send a new request from the frontend to a test endpoint to verify this flow, I can see the cookie is being passed back to the API in the headers, shouldnt it just work at that point? In the server logs I see the following:
dbug: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9]
AuthenticationScheme: Cookies was not authenticated.
dbug: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9]
AuthenticationScheme: Cookies was not authenticated.
Any ideas on where to go next?
20 Replies
Thalnos
Thalnos2mo ago
you have to choose between session based auth and token based auth, token based auth being preferred and the default of OAuth. If you use token based auth, you will need the token everytime to authorize on an endpoint. You pass it with the Authorization header the cookie doesn't authorize you, a token does
Espionage
EspionageOP2mo ago
Im with you, but theres no reason for me to do a JWT as I don't forsee anyone interacting with my API at that level. It's purely going to be my React App that talks to it - so Im going to aim for a session based auth. What I thought though, was that Identity would handle not only a session, but the authorisation - and that passing the cookie back and forth served as a client token for the session. Otherwise whats the utility of the SignInManager, why would it then delegate responsibility of session management back to me, isn't its purpose to resolve this part of the journey?
Thalnos
Thalnos2mo ago
I dont see yet why you wanna do session based auth here. Token based auth is better cuz its stateless, your backend should not have to hold state from a session. The recommonended flow for this type of architecture with React SPA hitting Asp.Net Core backend is authorization code flow with PKCE https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce
Thalnos
Thalnos2mo ago
No description
Espionage
EspionageOP2mo ago
I currently receive an access token from my React App, which I verify as having come from my Auth provider. If i verify it succesfully, I pass the user email to userManager and create them, or retrieve their existing account. With that account, I call signinmanager.SignInAsync(user, isPersistent: true); Then I have a route setup with [Authorize] and i guess unintuitively to me, theres an additional auth step I need? I'll read through that, and see whether its worth the effort to rip out what I've done or not and take that approach - but I dont see why my current approach would be outside the realm of feasible.
Thalnos
Thalnos2mo ago
what exactly does SignInAsync do?
Espionage
EspionageOP2mo ago
Well thats the question isn't it, its a method on SignInManager<IdentityUser> And my understanding was that it abstracted away the bits and pieces for me and just set the HttpContext.Response headers with everything it needed for Authroization.
Thalnos
Thalnos2mo ago
it might do that
Then I have a route setup with [Authorize] and i guess unintuitively to me, theres an additional auth step I need?
passing the AccessToken with the Authorization header is the additional step you need. You gotta pass it on every request on an endponiit that requires authorization.
Espionage
EspionageOP2mo ago
Well, I guess where Im lost is that I dont want to use the original token for anything other than trusting my frontend has completed OAuth. I dont reallly want to generate a new access token just for the sake of it, because isnt the whole thing that httponly cookies are a valid auth mechanism in and of themselves - AccessTokens aren't a requirement of authentication, they're an alternative solution I know for sure I can make it work with Access Tokens, but I dont think they're inherently required to acheive the outcome here i guess is where I'm at. I'll fiddle with it some more i guess or wait for some more feedback - but adding tokens just because I dont understand whats going on isn't something I want to do as I'm really trying to understand whats fundamentally wrong with this approach.
Thalnos
Thalnos2mo ago
I dont reallly want to generate a new access token just for the sake of it
you don't need to, you can use the old one as long as its not expired, and if it is expired you can use refreshtoken to create a new one without the user having to log in again they are required as long as you use token based auth with OAuth which you seem to be doing
Espionage
EspionageOP2mo ago
Well again, I dont want to use the token, because its only utility in life is to be a trust provider. I have no use for the token and I'd rather if i was going to pass a token around, generate my own. I use Token Based OAuth, only to the point of obtaining a valid access token from a provider. And I pass that token to my API, where I perform validation of the token. If the token is valid, then I take the user's email - and I never care about Oauth again. The token has served its purpose at this point for me. I want them to then have a valid session with my API, and I dont need the original token from the provider. At this point I said to myself, why do I need an Access Token, cant I just setup a session?
Thalnos
Thalnos2mo ago
this is not how OAuth should be used. The Verification of a valid accesstoken should happen everytime your backend gets hit you can set up a session yes but it would be worse than using token based auth
Espionage
EspionageOP2mo ago
That assumes token based authentication though, and I don't see why it would inherently be worse.
Thalnos
Thalnos2mo ago
server has to hold state for each user session. Token based auth is stateless
Espionage
EspionageOP2mo ago
I think thats of no consequence except performance no?
Thalnos
Thalnos2mo ago
scalability, hosting cost, you name
Espionage
EspionageOP2mo ago
Like my server has sessions, I store sessions in db, sessions tie to users tie to roles. It's a small app for a sub 10 user operation, why should I add the complexity of JWT(i know its minimal, but its the principal)? I think that the approach your describing works and is the default case when your planning to build a distributed system with multiple services, but I'm not. I'm building a dedicated application with a frontend whose only meaning in life is to talk to this single API and perform crud operations. The only reason I use OAuth is to validate users within the organisation, so they don't have to login to the system and manage multiple credentials. And if I dont want to use an access token, I'm sure I dont have to, Im just not familiar enough with Identity. If I envision the project scaling to larger sizes - I might consider the complexity as worth while, as yes an access token is more useful when you have multiple API's for a user to interact with (I'm not arguing against JWT's) - but in my case, with a single API I just dont see why I should take that direction yet. And nobody has yet chimed in with any domain knowledge on cookie based authentication to say that my approach is wrong. I guess the one thing I am missing, is session right now in my implementation, so I'll add it and see if thats the secret sauce.
Thalnos
Thalnos2mo ago
I use it as the default case of any system, not just distributed ones. and I'd argue the implementation of session based auth has higher copmlexity, its something you gotta do extra now while you've already got the token based auth setup. If you are not convinced by what I've said till now then wait for what other people here will say its more work for your server, for your db, and for you as a dev too from what I understand
Espionage
EspionageOP2mo ago
I ended up solving for the problem - I had mistakenly used the wrong Authentication scheme when setting up. I had: CookieAuthenticationDefaults.AuthenticationScheme I needed: IdentityConstants.ApplicationScheme This works:
builder.Services.AddAuthentication(IdentityConstants.ApplicationScheme)
.AddCookie(options =>
{
options.LoginPath = "/account/login";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Strict;
});
builder.Services.AddAuthentication(IdentityConstants.ApplicationScheme)
.AddCookie(options =>
{
options.LoginPath = "/account/login";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Strict;
});
Thalnos
Thalnos2mo ago
nice

Did you find this page helpful?