Closed marcotn closed 4 months ago
Hi, I haven't confirmed this but I suspect you can add EmployeeID to the list of ID token claims in AzureAD, which you should then be able to access from the django session (ID token claims are stored on the session), for example in a view:
employee_id = request.session['id_token_claims'].get('EmployeeID')
Hi I was a bit in a hurry and I managed to do it this way (I know it's ugly) but it works.
class SasaAuthHandler(AuthHandler):
"""
Class to interface with msal
package and execute authentication process.
"""
def __init__(self, request=None):
super().__init__()
self._extra_fields = settings.AZURE_AUTH_EXTRA_FIELDS
def authenticate(self, token: dict) -> UserModel:
"""
Helper method to authenticate the user. Gets the Azure user from the
Microsoft Graph endpoint and gets/creates the associated Django user.
:param token: MSAL auth token dictionary
:return: Django user instance
"""
_extra_returned = {}
azure_user = self._get_azure_user(token["access_token"])
if self._extra_fields:
_extra_returned = self._get_azure_extra_fields(token["access_token"])
# Allow for `outlook.com` users with email set on the
# `userPrincipalName` attribute
email = (
azure_user["mail"]
if azure_user.get("mail", None)
else azure_user["userPrincipalName"]
)
# Using `UserModel._default_manager.get_by_natural_key` handles custom
# user model and `USERNAME_FIELD` setting
try:
user = UserModel._default_manager.get_by_natural_key(email)
except UserModel.DoesNotExist:
user = UserModel._default_manager.create_user(username=email, email=email)
user.first_name = attr if (attr := azure_user["givenName"]) else ""
user.last_name = attr if (attr := azure_user["surname"]) else ""
user.save()
if user.username in settings.AZURE_AUTH_ADMINS:
user.is_superuser = True
user.is_staff = True
if self._extra_fields:
for _k, _v in self._extra_fields.items():
_attr = getattr(user, _v)
if _attr:
setattr(user, _v, _extra_returned.get(_k))
user.save()
# TODO: Handle groups
return user
def _get_azure_extra_fields(self, token):
_extra_fields = ''
for _extra_field in self._extra_fields:
_extra_fields += f"{_extra_field},"
_extra_fields = _extra_fields[:-1] #chop off the last ,
url = f'https://graph.microsoft.com/v1.0//me?&$select={_extra_fields}'
headers = {
'Content-Type': 'application\json',
'Authorization': f'Bearer {token}',
'ConsistencyLevel': 'eventual'
}
result = {}
r = requests.get(url, headers=headers)
ret = r.json()
for k,v in ret.items():
if k in self._extra_fields:
result[k] = v
print(result)
return result
Hi, sorry for the delay. Thanks for the example - please feel free to submit a PR!
Hey @marcotn thanks for the suggestion. On thing that I just saw is, since you are not saving the user, this settings will not be saved if there are no _extre_fields.
if user.username in settings.AZURE_AUTH_ADMINS: user.is_superuser = True user.is_staff = True
Have you considered to submit a PR for this change? I would also be interested in saving additional attributes to the user model. If not I try to replicate it and create a PR for this.
Hey @marcotn thanks for the suggestion. On thing that I just saw is, since you are not saving the user, this settings will not be saved if there are no _extre_fields.
if user.username in settings.AZURE_AUTH_ADMINS: user.is_superuser = True user.is_staff = True
Have you considered to submit a PR for this change? I would also be interested in saving additional attributes to the user model. If not I try to replicate it and create a PR for this.
Hi Sebastian, thanks for the suggestion, right now I have very little time so I cannot work seriously on a PR but if you need I can send you my code.
This issue should be handled in the same fix as for #23 as per https://github.com/Weird-Sheep-Labs/django-azure-auth/issues/23#issuecomment-2112293823
Please see https://github.com/Weird-Sheep-Labs/django-azure-auth/issues/23#issuecomment-2142771398 for an update.
Hi, do you think it would be possible to retrieve some extrafields from AzureAD during authentication, I am thinking about the EmployeeId .. do you have any suggestion about how to do it and in case I can make it would you be interested in a pull request ?