I was recently trying to make django authenticate into Azure MySQL using azure managed identity, and developed a simple package/hack to accomplish that. The main difficulty was that Azure MySQL expects a security token instead of password, and this security token refreshes every 30 minutes. So, before opening new connection one has to obtain the security token form the Entra ID (Active Directory). I have created new DB backend based on django.db.backends.mysql, which simply overloads DatabaseWrapper class
class DatabaseWrapper(DatabaseWrapper):
def get_connection_params(self):
kwargs = super().get_connection_params()
settings_dict = self.settings_dict
if settings_dict["CLIENTID"]:
clientid = settings_dict["CLIENTID"]
kwargs["password"] = self._get_db_token(clientid)
return kwargs
@async_unsafe
def _get_db_token(self, clientid):
credential = ManagedIdentityCredential(client_id=clientid)
access_token = credential.get_token('https://ossrdbms-aad.database.windows.net/.default')
return access_token.token
I haven’t tested the code thoroughly yet, as it requires to be deployed inside azure for Managed Identity feature to work. But, it seems to work fine for my internal Web App.
The question is how reliable is the approach I was taking in production settings? (I feel I might have screwed up something with async…).
Is there any point in adding something like this into Django, or perhaps it is better to release this as 3rd party django db backend?