-
Notifications
You must be signed in to change notification settings - Fork 28
Description
Hello,
I've been using fastapi_msal for a while (thanks for that!), and it's working quite well. There's just one thing that I haven't been able to do: force the refresh of a token before it expires.
The whole process is:
- the user opens the single-page webapp
https://myui.subdomain.net https://auth.subdomain.net/tokenis called from the UI using Javascript'sfetch()and it returns a 401 as the user is not authenticated yet- the user is redirected to M$ login
- the user is redirected back to the UI and
/tokenis called again to get the JWT from the Auth webapp - after 1h, the JWT expires, and is not refreshed, even if the user is active during that time
The UI and the Auth webapp are 2 different apps (not the same source code, not the same purpose), each has its own domain.
Things I did
I'm using this config:
class AppConfig(MSALClientConfig):
# This is a default configuration and is overriden by config.env files
base_url: str
grant_type: Optional[str] = "client_credentials"
login_path: Optional[str] = "/AADLogin"
logout_path: Optional[str] = "/AADLogout"
scopes: list[str] = ['user.read']
servers: Optional[List[str]] = [
"localhost"
]
token_path: Optional[str] = "/set_token"
redirect_uri: str
@property
def return_to_path(self) -> str:
return self.base_url + "/AADCallback"
client_config = AppConfig(....)I'm using this MSALAuthorization:
msal_auth = MSALAuthorization(client_config=client_config, return_to_path=client_config.return_to_path)Note: I tried different things when setting up return_to_path initially, maybe some clean-up is needed here.
And the app:
def create_app():
_app = FastAPI()
_app.add_middleware(
SessionMiddleware,
secret_key=client_config.client_credential,
max_age=3600,
same_site="lax",
domain=None if "localhost" in client_config.base_url else "mydomain.net",
https_only=False if "localhost" in client_config.base_url else True
)
_app.include_router(msal_auth.router)
return _appAnd finally, I have this route to return the token to the user as a JSON object:
@app.get("/token")
async def get_token(request: Request, response: Response):
token: Optional[AuthToken] = await msal_auth.get_session_token(request=request)
return tokenI also have routes for /login, /logout, and other routes related to callbacks from AAD.
What I'd like to do
From the /token endpoint, I would like to test if the token is about to expire (I know how to do that), and if that's the case, I want to refresh it.
I tried a few things, like:
# in this case, token is None
token = await msal_auth.handler._get_token_from_cache(session=request.session, user_id="my-oid")Or:
# In this case, 'accounts' is empty, so 'token' is None
accounts = await msal_auth.handler.msal_app().get_accounts(username=token.id_token_claims.preferred_username)
token = await msal_auth.handler.msal_app().acquire_token_silent(account=accounts[0], force_refresh=True)Is there something I'm missing in terms of code or config ? Am I on the right track ?
Thank in advance for your help.