dotnet-websharper / core

WebSharper - Full-stack, functional, reactive web apps and microservices in F# and C#
https://websharper.com
Apache License 2.0
593 stars 52 forks source link

Switch to header-based authentication #1338

Open Jand42 opened 1 year ago

Jand42 commented 1 year ago

Current WebSharper RPC can be used best with cookie-based auth and has CSRF-protection built in. You are required to set up .AddAuthentication("WebSharper").AddCookie("WebSharper", fun options -> ()) in your Startup as RPC+Sitelets will look for AuthenticationScheme="WebSharper" by default (you can also configure that). WS adds CSRF-protection on top of this automatically with an x-csrftoken header.

The only thing important for CSRF is that we cannot rely on cookie auth only, bc a malicious website could send JSON request to your API and have the browser auto-append your cookie for the session. How WS protects against this is that it also makes a x-csrftoken header from the cookie, and only scripts running from your site's url can have read access to the cookie, so the server can check cookie and header is the same and only then it allows the request through.

This is a bit limiting, makes it so that a WebSharper site's scripts must be served from the same domain as the RPC API. You can use WebSharper Sitelet's JSON API to decouple API+UI but then you need to implement your own CSRF-protection if you would rely on cookie-based auth.

So probably best approach to modernize is to move to support Authentication headers instead for RPC by default too. On the client, the best practice is to save auth token in localstorage, we can add this as an overridable method on the default RemotingProvider implementation (customizable client-side helper class for handling remoting). When a user is logged in on the server, it would send Authorization header in response, RemotingProvider would intercept it and save in localstorage, and send as Authorization header on any RPC request.