Cookies in IdentityServer4 - asp.net

Can someone explain the purpose of the cookies which are sent to the user browser after successful login in Identity Server4. Also I have three smaller related questions at the bottom.
The client is using cookie middleware in ASP.NET Core defined in the Startup.cs file.
app.UseCookieAuthentication()
It's quite obvious which tokens Identity Server created and which cookies the ASP.NET Core middleware creates, but I'm not sure what content each cookie containts.
ASP.NET Core middleware decided to create chunked cookies probably due to the cookie size (4050B + 865B).
I have been trying to find a way of decrypting the cookies to read the values using the Data Protection API provided by ASP.NET Core without any luck.
idsvr
idsvr.session
.AspNetCore.coookie
.AspNetCore.coookieC1
.AspNetCore.coookieC2
.AspNetCore.Antiforgery.
Which cookie contains the id_token, access_token issued by Identity Server?
CookieName can be used to change the name of the cookie created by ASP.NET Core middleware, should different clients share same cookie name or do they need to have separate session cookies?
Can the Identity Server cookies be decrypted by using the Data Protection API?

AFAIK id_token, access_token are not stored in a cookie by default. But you can store them in the session cookie(cookie created by ASP.NET Core middleware) if needed. Here is how it is done for identity server 3 with hybrid flow using OpenID connect OWIN middleware. There should be a similar option for asp.net core middleware as well.
Each client can have same cookie name but they are not required to do so. BY THE WAY, The cookie can only be accessed by the client who created it.
I do not know.

Related

Handling Logout in .NET Core (api side) with Cookie Authentication and OpenIdConnect

I'm working on an API core application with .NET core 5.
I protected the API with the following methods:
Cookie authentication
OpenIdConnect authentication (tokens kept in cookies, provided by an identity provider)
Custom session in memorycache
I use a derivated CookieAuthenticationEvents to manage sessions, overriding the methods :
ValidatePrincipal : I check token expiration (local, no request to identity provider) and existence of user in custom session
SigningIn : add in session if not exists
It works fine, and now i wonder how to handle the Log out.
I thought about the solutions, when client hits ly Logout API endpoint:
Calling logout to identity provider. It does invalidate token, but cookies on client side aren't deleted
Deleting user in my custom session. It does work, cookies still exist on client side but ValidatePrincipal will reject since no custom session for that cookie
Are those solutions "clean" ?
Or is there a .NET way to tell client to delete cookies / invalidate cookie ?
Thank you
EDIT
I tried it does delete cookies :)
HttpContent.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme)
There is one too ut i don't understand what it does, cookies aren't deleted and token isn't revoked on identity provider
HttpContent.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme)

shared authentication with cookie and token in identity server

I’ve an MVC application that uses identity server with cookie based authentication.
We created a new spa application that uses identity server authentication through bearer tokens.
Everything works fine, but the user is currently required to log in twice, once in each app.
Is there a solution to share the authentication session? I would prefer to not have to decrypt the cookie from the spa if possible.
Edit:
What I see is that the authentication code flow on the SPA is populating a lot of values on the session storage, which are not picked up by the the MVC (client credentials flow) application.
Am I supposed to reflect those changes manually? I see that both populate a cookie with the security information, but the SPA is just ignoring it.
In the end the reason was due to the difference in casing for the Authentication/authentication endpoint.
The cookies for idsrv and idsrvsession were marked as case sensitive, so we ended up having two different cookies for the session (hence creating 2 different sessions).
Changing one of the two endpoint to match the other solved the issue, although a CR forcing a tolowercase of the parameter has been requested to the library performing the connection to identity server.

Can we secure a dotnet core 2.0 React App with only aspnet identity?

I am building a SPA using React and Redux on top of dotnet core 2.0. Unfortunately, the vs2017 template for this does not include Authentication/Authorization.
In looking around, I saw many people talking about the use of JWT's and suggesting things like Identity Server or OpenIddict to handle this, but I have only ever used ASP.NET identity to handle security before.
My question is, is it possible to secure a react app by using ASP.NET identity alone, and if so, why do so many people jump straight to JWT's as the solution for securing SPA apps?
Is token based authentication the only method that works with a SPA app, or can I use Cookie based authentication?
I will try to answer by your questions.
Q.1. Is it possible to secure a react app by using aspnet identity alone, and if so, why do so many people jump straight to JWT's as the solution for securing SPA apps?
Q.2. Is token based authentication the only method that works with a SPA app, or can I use Cookie based authentication?
Answer To First Question(this question technically related to difference between cookie based and token based authentication approach.)
Cookie based authentication system
cookie based session is StateFull. as here server needs track of active session,while on front end/client end a cookie is created that holds a session identifier.
you can secure your web api using cookie based authentication system. but in a very limited scope, because ,cookie based system doesn't work well, on native clients or suppose if your web api is going to be consumed by some other web api,
Token based authentication system
it is StateLess as server doesn't keep here the track of which token are issued or which users are log in.
Here server needs to verify only the validity of the token. so token based approach is more decupled than cokie based.
Sources
https://auth0.com/blog/cookies-vs-tokens-definitive-guide/
Update Above(Auth0) link not working any more Updated Link
https://learn.microsoft.com/en-us/dotnet/standard/microservices-architecture/secure-net-microservices-web-applications/
Answer To Second Question
Yes you can implement cookie based authentication in spa by using OWIN Cookie Authentication middileware .
you can find more information regarding it on following link.
https://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/
Hope above will help.
If you are going to have React and API in one domain, and the SPA would be the only client of API it may be recommended to use cookie based authentication with SameSite Cookies.
https://www.scottbrady91.com/OAuth/Cheat-Sheet-OAuth-for-Browser-Based-Applications
https://brockallen.com/2019/01/03/the-state-of-the-implicit-flow-in-oauth2/
(section same-domain apps)
longer post: https://blog.cdivilly.com/2020/06/10/oauth-browser-apps

How to change session token/cookie format in cookie when navigates to other website?

I have 2 web applications, one is ASP.NET MVC 5 + WIF hosted in IIS, another is a web service based on WCF and self-hosted. Both of them are under same domain (so there are no security issues to change cookie format) and referring to the same STS (in same security realm), so theoretically if one user already authenticated, he should be able to access other entities within same security realm without authentication.
However, these 2 websites are using different session token format. For ASP.NET MVC 5 project, it uses WIF implemented standard security session token and serialized to cookie; for WCF web service, it uses its own token/cookie format.
Then we have a problem.
When user navigates from ASP.NET MVC website to WCF web service, because WCF web service cannot recognize WIF session token (FedAuth and FedAuth1), so it redirects user to STS and login again, that is not the biggest problem, the biggest problem is, after use logged in, and POST raw SAML2 token back to WCF web service, WCF web service creates its own format token and tries to set client cookie, it actually doesn't work, I guess maybe there are already FedAuth and FedAuth1 cookie in header so header cannot accommodate more tokens (4K limit?)? Having thought about this for a while, there are are several solutions come into my mind:
Unifying token format. I need to subclass SecurityTokenHandler (maybe also need to subclass CookieHandler), use the same token format that WCF service uses, so when jumps to WCF web service, it can recognize the session token. That needs to dig deep into FAM and SAM.
Force re-login. I can clear FedAuth and FedAuth1 cookies before navigates to WCF web service, it is acceptable that user needs to login again, this is a short term fix, but how can I capture this navigation away event and clear cookie? The only way I think I can do is before I change window.location.href, use jQuery.cookie to clear cookie, I am not sure if it is the correct way, this is my first question.
Adding a cookie translation layer between ASP.NET and WCF, use WIF session token in ASP.NET website, and when jumps to WCF web service, change the token format. But for this solution I don't know how to capture the jump action and how can I get raw SAML2 token? May be I can save it in WSFederationAuthenticationModule_SecurityTokenReceived event handler? But how to deal with multi tokens from multi users and multi sessions?
Are there other better suggestions?

Windows Identity Foundation: How to get new security token in ASP.net

I'm writing an ASP.net application that uses Windows Identity Foundation. My ASP.net application uses claims-based authentication with passive redirection to a security token service. This means that when a user accesses the application, they are automatically redirected to the Security Token Service where they receive a security token which identifies them to the application.
In ASP.net, security tokens are stored as cookies.
I want to have something the user can click on in my application that will delete the cookie and redirect them to the Security Token Service to get a new token. In short, make it easy to log out and log in as another user. I try to delete the token-containing cookie in code, but it persists somehow.
How do I remove the token so that the user can log in again and get a new token?
I found the solution. To put it succinctly:
Dim smartWsFederationAuthenticationModule As _
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule = _
HttpContext.Current.ApplicationInstance.Modules("WSFederationAuthenticationModule")
smartWsFederationAuthenticationModule.SignOut(True)
See here for more information: http://garrettvlieger.com/blog/2010/03/refreshing-claims-in-a-wif-claims-aware-application/
I also see that I can get handles to some other parts of the WIF framework this was, as well. It's definitely worth the read.
Cookies are a bit strange. They are managed by the browser and there is no "Method" to delete them. Just deleting them from the Request or Response objects on the server side does not remove them from the browser on the client side.
To "Delete" a cookie you have to set it's expiration date to the past.
See: http://msdn.microsoft.com/en-us/library/ms178195.aspx

Resources