diff --git a/fastapi_msal/models/base_auth_model.py b/fastapi_msal/models/base_auth_model.py index 994eca0..b9cbc2a 100644 --- a/fastapi_msal/models/base_auth_model.py +++ b/fastapi_msal/models/base_auth_model.py @@ -1,6 +1,6 @@ from typing import Optional, TypeVar -from pydantic import BaseModel, PrivateAttr +from pydantic import BaseModel, ConfigDict, PrivateAttr from fastapi_msal.core import OptStrsDict, SessionManager, StrsDict @@ -9,6 +9,14 @@ class BaseAuthModel(BaseModel): _recieved: OptStrsDict = PrivateAttr(None) + model_config = ConfigDict(extra="allow") + """ + extra="allow" + for Pydantic to save additional fields that are not defined in the model. + Since the ID token can have additional fields defined in the app registration portal. + To access these fields (if any), use the `__pydantic_extra__` attribute of the object. + https://docs.pydantic.dev/latest/concepts/models/#extra-fields + """ @classmethod def parse_obj_debug(cls: type[AuthModel], to_parse: StrsDict) -> AuthModel: diff --git a/fastapi_msal/models/id_token_claims.py b/fastapi_msal/models/id_token_claims.py index f7252b9..7ad6cfe 100644 --- a/fastapi_msal/models/id_token_claims.py +++ b/fastapi_msal/models/id_token_claims.py @@ -8,6 +8,7 @@ from fastapi_msal.core import MSALPolicies, OptStr, OptStrsDict +from .base_auth_model import BaseAuthModel from .user_info import UserInfo @@ -76,7 +77,7 @@ class AADInternalClaims(BaseModel): """ -class IDTokenClaims(UserInfo, AADInternalClaims): +class IDTokenClaims(UserInfo, AADInternalClaims, BaseAuthModel): """ The ID token is a security token that contains claims about the authentication of an end-user by an authorization server, when using a client, and potentially other requested claims. @@ -193,6 +194,13 @@ class IDTokenClaims(UserInfo, AADInternalClaims): _id_token: Optional[str] = PrivateAttr(None) """ The raw id_token that was used to create this object - private attribute for internal use only + Will be set only via the `decode_id_token` method + """ + + _decoded_token: OptStrsDict = PrivateAttr(None) + """ + The decoded token that was used to create this object - private attribute for internal use only + Will be set only via the `decode_id_token` method """ @staticmethod diff --git a/fastapi_msal/models/user_info.py b/fastapi_msal/models/user_info.py index 0817078..df455c2 100644 --- a/fastapi_msal/models/user_info.py +++ b/fastapi_msal/models/user_info.py @@ -1,8 +1,8 @@ -from typing import Optional +from typing import Optional, Union from pydantic import BaseModel, Field -from fastapi_msal.core import OptStr, OptStrList +from fastapi_msal.core import OptStr, OptStrList, StrList class UserInfo(BaseModel): @@ -93,3 +93,16 @@ class UserInfo(BaseModel): Indicates that the client should use the Microsoft Graph API to determine the user's groups (https://graph.microsoft.com/v1.0/users/{userID}/getMemberObjects). """ + + groups: Union[StrList, str, None] = None + """ + Provides object IDs that represent the group memberships of the subject. + The groupMembershipClaims property of the application manifest configures the groups claim on a per-application basis. + A value of null excludes all groups, a value of SecurityGroup includes only Active Directory Security Groups, + and a value of All includes both Security Groups and Microsoft 365 Distribution Lists. + + See the hasgroups claim for details on using the groups claim with the implicit grant. For other flows, + if the number of groups the user is in goes over 150 for SAML and 200 for JWT, + then Microsoft Entra ID adds an overage claim to the claim sources. + The claim sources point to the Microsoft Graph endpoint that contains the list of groups for the user. + """