Leonard: At least I didn’t have to invent 26 dimensions just to make the math come out.Sheldon Cooper, Leonard Hofstadter
Sheldon: I didn’t invent them, they are there!
Leonard: In what universe?
Sheldon: In all of them, that’s the point.
I always liked that exchange in the Big Bang Theory. Still a great show.
Anyway. There’s been a few applications/components that I’ve had to work on where I needed to access an API that used Bearer Authentication. I wrote an authentication class for managing the lifecycle of the bearer token, including the acquisition/generation and refresh of the token. I’ve extracted that code and put it GitHub. It’s designed to simply forget about – you tell the authentication class to start, and it sorts itself out. If the bearer token times out or stops working, it creates a new bearer token. If the bearer token can’t be created, it creates a new pairing token and so on.
The particular example that I extracted the code from, needed the client to first pair with the API service – which is typically done once for the lifetime of the client app being in use, and then that pairing token is used to generate a session based bearer token. This token then needs to be refreshed periodically.
In the Authentication.Initialise() method, you supply the authentication class with the appropriate credentials – in this case a username and password. You also supply the HttpClient instance that you will use for accessing the API, and finally a ManualResetEvent instance used to stop the token monitor (you could also just add a Stop() method). That HttpClient instance will be given a default HTTP header with the bearer token attached so that any calls you make using that instance will be authenticated.
I’ve written the Authentication.Initialise() method to generate a device identifier, and then save that to a file so that it persists.
Authentication.TokenMonitor() is the primary method that does the work, and is launched as a child thread by the Authentication.Initialise() method. The token monitor checks to see if there is a valid pairing token – if not, it creates one using Authentication.GetPairingToken(). Once it has the pairing token, it then uses Authentication.GetBearerToken() to generate the bearer token.
The token monitor then sleeps for 60 seconds (_iAuthenticationInterval). Every 60 seconds, it checks to see if the token is nearing its refresh time, and then refreshes the token. You could also simply change the poll timer dynamically to the lifetime of the bearer token so that your loop doesn’t execute as frequently.
I’ve added an AutoResetEvent as well which is exposed as a property of the class – Authentication.AuthenticationFailure. If any of your API calls fail due to authentication, triggering that event will force the token monitor to regenerate the bearer token.
If Authentication.GetBearerToken() fails to generate a bearer token, it will invalidate the pairing token, forcing Authentication.GetPairingToken() to be called to regenerate a new pairing token.
You’ll need to adapt the class to the appropriate URLs/pages of the API and the authentication system, and provide whatever credentials, device identifiers etc that the API requires.
If you’ve got any questions about the code or the method, please leave a comment below!