Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distributed Authentication

I wanted to implement a certain architecture that decouples my rest API from a web server that would be used as an agnostic template engine such as DustJS. My back end rest API would be built using service stack.

The main thing that I like about service stack and NodeJS is that they both provide a way to authenticate but I only need a central way to access credentials for granting access to API calls as well as restricting certain content on my views.

The application I want to develop is a subscription based dating website, so that presents me with a few problems. The parameters involved are roles, groups, authenticate and authorize. It's easy to implement on service stack but I am confused with mainly how the front end could get access to that information.

How would I implement a scenario where the front end retrieves credentials once and does not have to keep making API calls to check the DB or Cache to see if it checks out? Do I need to implement a different method in handling clients who wish to remain logged in, or does that typically get solved just by setting a time stamp value?

Thanks for your time everyone.

like image 282
Denis Cekic Avatar asked Sep 27 '22 08:09

Denis Cekic


1 Answers

Sessions are just AuthUserSession POCO's stored in a Cache

The way Authentication works in ServiceStack (and most web frameworks) is that when a User successfully Authenticates, an Authenticated UserSession is created for that User and stored in the registered Caching Provider you've registered in ServiceStack's AppHost. The session id for that the Authenticated UserSession (aka AuthUserSession) is then stored in the Users cookies under the ss-id Temporary and ss-pid Permanent cookies.

Session Cookies re-sent on each request

Cookies by design are re-sent on every subsequent request to that domain which is how Server frameworks know which Authenticated User is making each Request by simply retrieving the AuthUserSession from the Caching provider stored under the following key:

urn:iauthsession:{sessionId}

Where {sessionId} is either the Temporary (ss-id) or Permanent (ss-pid) cookie depending on whether the User Authenticated with ?RememberMe=true or not. This also means your node servers can also easily access a Users Session authenticated with ServiceStack by accessing the same cache with the above key format.

Most caching providers are distributed

All Caching providers except for the MemoryCacheClient (default) are distributed which means that each of your load balanced App Servers will naturally be able to tell if the User is Authenticated or not.

Accessing User Sessions is very cheap

I wouldn't be concerned with performance for retrieving the UserSession since accessing a User Session only takes a single cache hit to access the blobbed Users Session at a single key - which is closest to the cheapest network request your Server can do.

Can avoid network requests with a Write-thru Cache

One way you can avoid the single cache request to retrieve a Users Session is with a write-thru cache where when a User is authenticated it is saved in both a local MemoryCacheClient as well as a distributed ICacheClient (e.g. Redis) that way when the request for a Users session is requested it first looks at the local cache and if it doesn't exist will call the distributed cache to fetch it, storing it in the local cache before returning it. The one thing you need to watch out for is to synchronize any changes to the distributed cache with the local caches stored in the memory of all the load-balanced App Servers which you can use something like Redis Pub/Sub to send messages between all the different App Servers.

like image 77
mythz Avatar answered Sep 30 '22 14:09

mythz