Skip to content

Question: refresh token on demand #51

@ph--

Description

@ph--

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/token is called from the UI using Javascript's fetch() 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 /token is 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 _app

And 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 token

I 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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions