Add the ability to view the authentication server session identifier returned from ITicketStore.
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Is your feature request related to a problem? Please describe the problem.
Developers who use ASP.NET Core to create OAuth/OpenID Connect providers often require a mechanism to work with server-side sessions. For instance, they may need to implement a deferred Back Channel Logout Notification, which involves placing the identifier of the ended user session in a queue by the provider when the user logs out from the Identity Provider (IDP). This allows all client applications to be notified of the session termination in the background, ensuring that the logout operation doesn't take up too much time.
In the standard CookieAuthenticationHandler, there is an [ITicketStore](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Security/Authentication/Cookies/src/CookieAuthenticationOptions.cs#L118-L122) designed for working with server-side sessions. However, the session identifier it returns is only stored in the cookie and there are no convenient ways to retrieve it directly.
If I need a server session identifier, the following options are available to me:
- Generate a separate "actual" surrogate session identifier before invoking the save operation in the database through ITicketStore, save it in ClaimsPrincipal or AuthenticationProperties, and subsequently access it appropriately.
- Write an implementation of ITicketStore that will use the key from the provided parameters as such an identifier and dynamically add it during reading, mutating the passed AuthenticationTicket, and remove it during writing (as this parameter serves as the key by which the AuthenticationTicket should be stored).
- Create a custom CookieAuthenticationHandler that enables dynamic addition and concealment of this identifier, similar to the previous approach, but at the authentication handler level without transferring this logic to the ITicketStore.
- In case the session identifier is generated by the database itself and I need to store it, and none of the previous options suit me, I am forced to first create a record in the database, then save the obtained identifier in ClaimsPrincipal or Authentication Properties, and then update the newly created record as well as mutate the passed AuthenticationTicket so that the code following the authentication handler can access this identifier.
- Create a separate cookie to store the server session identifier.
- Using the same DataProtection settings as the original authentication handler, independently read and decrypt the session identifier from the cookie using a separate extension method for HttpContext.
All these options seem fragile and inconvenient. Having a mechanism that would allow "pulling" the identifier, which is [created here](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Security/Authentication/Cookies/src/ITicketStore.cs#L37), retrieved from the cookie and [stored in runtime here](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs#L32), and [passed as a "key" parameter here](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Security/Authentication/Cookies/src/ITicketStore.cs#L88), would enable much more convenient handling of server sessions.
### Describe the solution you'd like
1) Add a separate public property to AuthenticationProperties for a non-serializable dictionary, similar to the Parameters property, but instead of input parameters, it will store output parameters of the authentication handler. Then, place the session identifier into this dictionary within the CookieAuthenticationHandler.
2) Add a separate nullable string property to [`AuthenticationProperties`](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Http/Authentication.Abstractions/src/AuthenticationProperties.cs) and make it non-serializable. This property would hold the value of the server session identifier after retrieving it from [`ITicketStore`](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Security/Authentication/Cookies/src/ITicketStore.cs). For example, near the code that sets the value in the private field [`_sessionKey`](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs#L32) in CookieAuthenticationHandler, a method call can be added to set the value of this property in AuthenticationProperties.
3) Use the [`Parameters`](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Http/Authentication.Abstractions/src/AuthenticationProperties.cs#L67) dictionary in AuthenticationProperties for these purposes. But I like this option less because `Parameters` is used for passing input parameters. On the other hand, [`Items`](https://github.com/dotnet/aspnetcore/blob/00d0038f937f0059a847fde504649fe33ec935e0/src/Http/Authentication.Abstractions/src/AuthenticationProperties.cs#L60) seems like a good candidate based on the description, but it is a serializable value that needs to be stored in a database. The scenario where we only learn the actual identifier after writing to the database is valid, and we shouldn't exclude it, so `Items` won't be suitable.
### Additional context
In this issue, I am indeed discussing authentication sessions implemented through ITicketStore. It is not related to regular sessions used for storing intermediate data, such as items in a shopping cart.
Contributor guide
Assessment
This issue has not been assessed yet.