11

I'm trying to set up a few .NET applications to use certificate-based authentication to Azure Active Directory and then use Active Directory to authorize my access to a Sql Azure DB.

The problem I'm running into is that some parts of the application use a DbContext that might live a little too long. The ADAL library tries to refresh the access token if you request it within 5 mins of it's expiration. Trouble is that some of my DbContexts might live for longer than 5 mins. Hence, halfway through the life of the DbContext the access token is no longer good and when I try to SaveChanges I get a database connection exception.

Apart from refactoring to make my DbContexts live shorter than 5 mins, is there anything I can do to fix this?

One thing I tried was to find some hooks in Entity Framework where I could catch the expired access token exception and then replace the current connection with a newly created one that has a new access token. I tried passing EF a custom connection factory and then using an Execution Strategy to retry when I get an expired token exception. This isn't working for me though because I can't modify or recreate the current connection from a custom execution strategy.

Any ideas would be greatly appreciated.

Thanks!

Nick
  • 695
  • 8
  • 23
  • This sounds like a bad idea. A context is intended to live for a unit of work, 5 mins sounds like you are doing lots of units of work with the same context. This will cause you other issues such as a high memory footprint and poor performance if you do too many things with a context. My recommendation would be to refactor your code (regardless of this specific issue) – undefined Sep 25 '16 at 23:58
  • Can you precise what version of EF you are using, also, are you using Identity framework ? – GaelSa Sep 27 '16 at 07:27
  • How are you passing access token to DbContext? Even if DbContext is living long, underlying DbConnection isn't living long, it is opened and closed for every sql query. – Akash Kava Sep 27 '16 at 07:42

1 Answers1

3

Refactoring your code is certainly the best option if you can afford it.

If you can't, you could set a timer to fire every 4 minutes, and in this timer do some simple query with the DBContext (this will refresh your authentication token if needed, ensuring it is still valid when you SaveChanges). You'll also need to protect the DBContext with some lock during this to avoid the simple query and SaveChanges using the DBContext at the same time.

Philippe
  • 1,225
  • 7
  • 9