umbraco / Umbraco.AuthorizedServices

Umbraco Authorized Services is an open-source package designed to reduce the effort needed to integrate third party services that require authentication and authorization via an OAuth flow.
MIT License
14 stars 7 forks source link

Fetch new token when while not having a refresh token #42

Closed mastrup closed 12 months ago

mastrup commented 1 year ago

Umbraco version: 12.3.1 Umbraco.AuthorizedServices version: 0.3.1

Issue

I have added a new service, using OAuth2ClientCredentials. My defined service looks like this:

"DanfossTerms": {
  "DisplayName": "Danfoss Terms API",
  "AuthenticationMethod": "OAuth2ClientCredentials",
  "ClientCredentialsProvision": "AuthHeader",
  "ApiHost": "https://e2e.api.danfoss.com/terms",
  "TokenHost": "https://e2e.api.danfoss.com",
  "AuthorizationUrlRequiresRedirectUrl": false,
  "RequestTokenPath": "/oauth2/token",
  "RequestTokenMethod": "POST",
  "RequestTokenFormat": "FormUrlEncoded",
  "ClientId": "<Set in Azure>",
  "ClientSecret": "<Set in Azure>",
  "AccessTokenResponseKey": "access_token",
  "ExpiresInResponseKey": "expires_in",
  "SampleRequest": "/privacypolicies?culture=en&include_content=true",
  "RefreshAccessTokenWhenExpiresWithin": "00.00:00:40"
}

When requesting a token from the endpoint, I get the following response:

{
    "access_token": "LgHqimayLHHpRVicBQLa2Ag2JayE",
    "token_type": "Bearer",
    "expires_in": "3599"
}

Everything works fine up until my returned token expires. I would expect Umbraco.AuthorizedServices to just fetch a new token, but I am getting the following response in Umbraco, when I click Verify Sample Request:

Authorized Services: The sample request did not complete: Cannot request service 'DanfossTerms' as the access token has or will expire and no refresh token is available to use. The expired token has been deleted.`

Looking at EnsureAccessToken(), it seems that my token always will get cleared when I don't have a refresh token present.

How would I go about fetching a fresh token before my token expires or when it has expired?

AndyButland commented 1 year ago

I think at that point it's necessary to go back into the backoffice and manually request another token. As without a refresh token, we would require the user to log into their account and accept the permissions before another access token would be issued.

Maybe there's some UI improvements we could consider here to make it a little more obvious when a token is expiring. But I'm not sure it's possible to handle in an automated way without user involvement. Open to suggestions though if you had an idea how this could work.

mastrup commented 1 year ago

As I understand, Client Credentials is meant for applications to obtain an access token outside of the context of a user.

It seems a bit counterintuitive that a user must actively request a new token when using Client Credentials as authentication method.

Ideally Umbraco.AuthorizedServices should just request a new token like it would for a refresh token, when using Client Credentials.

AndyButland commented 1 year ago

That's a good point... I'd missed that you were using the client credentials flow. We'll see what we can do as it does seem we've missed a part in this implementation.

mastrup commented 1 year ago

Sounds great! Thank you for looking into it.

AndyButland commented 12 months ago

You should find this resolved as part of the 0.4.0 release, which I've just pushed out to NuGet.

mastrup commented 12 months ago

This is great! Thanks Andy!