Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refreshing token support built in? #110

Open
developer992 opened this issue Dec 14, 2023 · 4 comments
Open

Refreshing token support built in? #110

developer992 opened this issue Dec 14, 2023 · 4 comments

Comments

@developer992
Copy link

developer992 commented Dec 14, 2023

Hello,

I am implementing SAP XSUAA Oauth2 via GenericSSO client and it works, good job!

I also receive back a refresh token after successful login

According to docs, refreshing the token involves creating a new request like so:

Refresh Token Grant

If the current access token is expired, a new one can be requested with the [Refresh Token  flow](https://docs.cloudfoundry.org/api/uaa/version/74.23.0/index.html#refresh-token).

Make a request:

POST https://[xsuaa.url]/oauth/token

Headers
Accept: application/json
Content-Type: application/x-www-form-urlencoded

client_id=[xsuaa.clientid]
client_secret=[xsuaa.clientsecret]
refresh_token=[refresh_token]
grant_type=refresh_token

Check the response:

{
  "access_token": [access_token],
  "token_type": "bearer",
  "id_token": [...],
  "refresh_token": [refresh_token],
  "expires_in": [...],
  "scope": [...],
  "jti": [...]
}

Congratulation, you now have a refreshed access_token.

I would like to know if this support is already built in or do we need to manually do this request?

Many thanks!

@developer992 developer992 changed the title How do i refresh token? Refreshing token support built in? Dec 15, 2023
@developer992
Copy link
Author

I rolled my own implementation, here's the code if anyone is interested.

class SAPXsuaaSSO(SSOBase):
    provider = "sap.xsuaa"
    scope = settings.DEFAULT_SCOPE

    async def get_discovery_document(self) -> DiscoveryDocument:
        return {
            "authorization_endpoint": f"{settings.XSUAA_API_URL}/oauth/authorize/",
            "token_endpoint": f"{settings.XSUAA_API_URL}/oauth/token/",
            "userinfo_endpoint": f"{settings.XSUAA_API_URL}/userinfo",
        }

    async def openid_from_response(self, response: dict, session: Optional[httpx.AsyncClient] = None) -> OpenID:
        return OpenIDUser(**response)

    async def token_refresh(self, refresh_token: str) -> OpenID:

        token_url, headers, body = self.oauth_client.prepare_refresh_token_request(
            token_url=await self.token_endpoint,
            refresh_token=refresh_token,
            scope=self.scope,

        )

        auth = httpx.BasicAuth(self.client_id, self.client_secret)
        async with httpx.AsyncClient() as session:
            response = await session.post(token_url, headers=headers, content=body, auth=auth)
            content = response.json()
            self._refresh_token = content.get("refresh_token")
            self.oauth_client.parse_request_body_response(json.dumps(content))
            uri, headers, _ = self.oauth_client.add_token(await self.userinfo_endpoint)
            response = await session.get(uri, headers=headers)
            content = response.json()

        return await self.openid_from_response(content, session)

@developer992
Copy link
Author

Thanks.

@tomasvotava
Copy link
Owner

@developer992 Hi and thanks for both the question and the solution! I am sorry I didn't have the time to come up with it before you did.

It's actually a good idea to bake the support for refreshing token in, I'll look into it over the holidays!

@developer992
Copy link
Author

Thank you man, happy new year as well :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants