In WSO2 Identity Server 5.9.0 I am using OAuth 2.0 Authorization Code. Access tokens are short-lived and are refreshed by refresh tokens. It implements current recommendation for SPAs and it works fine.
I also configured account disabling and I though that when I disable user which holds refresh token the user won't be able to get new access token. But /oauth2/token endpoint is issuing new tokens no matter if user is disabled or not. Is this expected? How can I deny given user to refresh access token?
I found a workaround. If locking is used instead of disabling then it works as expected. Submitted issue to WSO2.
Related
I created "test-App" application in API Manager WSO2 with the grant types of "refresh-token" "SAML2", "PASSWORD" "Client Credentials" and "JWT"
I also Created a "test"
To use the webservices behind API manager, First, I should call https://localhost:9443/oauth2/token) to get a access-token
Unfortunately, if I call the link again, instead of receiving the same access-token, the system will generate a new access-token and the previous access-token would be expired. ( I think this link is more like refresh token rather than get the access token).
So, How can I Separate getting available access-token and Refresh-token link in WSO2 API Manager ?
In the latest versions of API Manager you have JWT tokens. When you request a new token it always generates a new token. But it doesn’t revoke the previous access token.
In the earlier versions of APIM, opaque tokens were supported and it has a different behavior. When you request a token, if it is not expired you get the same token.
Please read more about refresh grant here https://apim.docs.wso2.com/en/latest/design/api-security/oauth2/grant-types/refresh-token-grant/
If you have not done any other configuration changes, invoking https://localhost:9443/oauth2/token URL will always generate a new JWT token without expiring the earlier one. However, the token validity can be changed in the Dev Portal while generating the access token.
After googling we came to know that invalid_grant which means refresh token is invalid.
Link to google oauth doc
We don't have any of these issues mentioned by google. Is this error related to something else rather than a refresh token.
More Info
We have access to read, write spreadsheet and send gmail
We fetch an access token for each request
Any help would be appreciated.
We're already in production and verified by google
Without seeing the full error message that being
Invalid_grant {Message here}
It is hard to help but from my experience is most often caused by one of the following.
Refresh token expire, app not in production.
There are serval reasons why a refresh token can expire the most common one currently is as follows.
A Google Cloud Platform project with an OAuth consent screen configured for an
external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
The fix is to go to google developer console on the consent screen and set your application to production, then your refresh token will stop expiring.
invalid_grant: Invalid JWT
{ “error”: “invalid_grant”, “error_description”: “Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values and use a clock with skew to account for clock differences between systems.” }
Your server’s clock is not in sync with NTP. (Solution: check the server time if its incorrect fix it. )
invalid_grant: Code was already redeemed
Means that you are taking an authentication code that has already been used and trying to get another access token / refresh token for it. Authentication code can only be used once and they do expire so they need to be used quickly.
Invalid_grant: bad request
Normally means that the client id and secrete you are using to refresh the access token. Was not the one that was use to create the refresh token you are using.
Always store most recent refresh token.
Remember to always store the most recent refresh token. You can only have 50 out standing refresh tokens for a single user and the oldest one will expire. Depending upon the language you are using a new refresh token may be returned to you upon a refresh of the access token. Also if you request consent of the user more then once you will get a different refresh token.
User revoked access
If the user revoked your access in their google account, your refresh token will no longer work.
user changed password with gmail scope.
If your refresh token was created with a gmail scope and the user changed their password. your refresh token will be expired.
Links
Oauth2 Rfc docs for invalid_grant error rfc6749
invalid_grant
The provided authorization grant (e.g., authorization
code, resource owner credentials) or refresh token is
invalid, expired, revoked, does not match the redirection
URI used in the authorization request, or was issued to
another client.
I'm experiencing a situation where:
I have a Google project, using an OAuth 2.0 Client (for web applications), to get consent for some scopes from users. The authorization parameters used in the redirect to Google uses the following values for the parameters (only including the possibly relevant params):
access_type - offline
response_type - code
include_granted_scopes - true
If a user consents access to the app, the app gets an access token to access the scopes granted.
If the same user consents again (while the previous access token hasn't been revoked yet) to the same app (using the same OAuth 2.0 Client), a new access token gets issued to the project.
The Google project has 2 different tokens now, and both access tokens work for accessing the scopes granted. Oddly though, the user would see only a single entry for the Google project/app in the users Apps with access to your account page.
The issue is that if any of the token gets revoked, all of the active tokens get revoked (attempts to use the access token results in an invalid_grant error, with the Token has been expired or revoked. error description). While I haven't tested beyond having 2 live/valid tokens at the same time, I suspect the behavior would be the same for more than 2.
I've been looking through the Google OAuth 2.0 docs to find some documentation regarding this behavior, or find anything referencing what happens to companion tokens when one gets revoked, but was unable to find anything explaining this behavior.
I, at first, thought that it was maybe due to my usage of incremental authorization, and thought that maybe revoking the latest access token revokes all preceding ones, but after experimenting with include_granted_scopes=false, the behavior was still the same.
For now, I've restricted users to be able to consent only once (unless a token expires), but I'm curious about the explanation for this behavior - where revoking 1 token revokes all of them.
Actually access tokens are independent. An access token by design will work for one hour. In theory even if the user revokes your access the access token will still work for the remainder of the hour it was originally valid for. This is standard Oauth2 functionality they are intended to give access for an hour that is why it is called a bearer token the bearer of that token is granted access for an hour.
What i suspect that you are seeing is the refresh token being revoked as this will cause a invalid_grant error. If you request access of the user using offline access you are granted a refresh token. If you request consent of the user again you get another refresh token. There can be up to fifty outstanding refresh tokens for a single user.
If the user revokes the access via their google account, or if your application revokes the access. Then yes all of the outstanding refresh tokens will be revoked. As your applications access to the users account has been revoked not the single refresh token. Note there are actually serval reasons why a refresh token can expire they can be found here refresh token experation
This is standard Oauth2 behavior not google specific.
Remove third-party account access
If you gave Google Account access to a third-party app or service you no longer trust or want to use, you can remove its access to your Google Account. The app or service won’t be able to access any more info from your Google Account, but you may need to request that they delete the data they already have.
community.
I'm using WSO2 IS 5.7.0 to integrate an Angular app with an external IDP.
The external IDP is configured with SAML2 and the service provider Inbound Authentication is set with Oauth/OpenID.
The service provider uses Federated Authentication to comunicate with the IDP.
The user uid from the IDP is matched with the claim userid, so when I ask for an oauth token, I get the correct scopes (matching a local user with roles configured) to use the token with WSO2 AM. This is working well whe I get the initial oauth token using code grant.
If I introspect this token, I can verify the token belongs to the username XXXXXXXX and the scopes are the ones to consume an API on WSO2 AM, based on the roles associated to the local user XXXXXXXX.
The problem is when the refresh token is used to get a new access token after expiration. The new access token comes with the same scopes, but I cannot consume the same API I was consuming with the first token. I get a 403 Forbidden on every call and the AM log shows:
WARN - APIAuthenticationHandler API authentication failure due to Invalid Credentials
(The first WARN appears only once)
WARN - APIAuthenticationHandler API authentication failure due to The access token does not allow you to access the requested resource
(this WARN appears on the subsequent calls)
If I introspect the receibed token, I can see the same scopes as the original access token, but the username is different:
FEDERATED/XXXXXXXX#carbon.super.
I think this username change on the token information leads to the 403 error.
The problem is worst if I activate the Service Provider option "Use tenant domain in local subject identifier" on the Local & Outbound Authentication Configuration. In this case, every time I ask for a new token with refresh token, the tenant is appended to the username on an infinite loop:
XXXXXXXX#carbon.super#carbon.super#carbon.super#carbon.super
On every token I get, the introspect shows me another #carbon.super is appended to the username of the actual token. In this case, the FEDERATED/ is not always present on the username.
I expect the username associated to the refreshtoken to be equal to the one on the first access token.
Is there a configuration to solve this or this is a bug? is resolved on new releases of WSO2 IS?
(sorry for my english)
Thanks!
Similar issue is reported[1] and fixed with PR[2].
[1] https://github.com/wso2/product-is/issues/4472
[2] https://github.com/wso2-extensions/identity-inbound-auth-oauth/pull/1022
If you don't have a WSO2 subscription, upgrading to the 5.8.0 will resolve the issue.
I am doing some work in Django, using the Django Rest Framework.
Users login via Oauth2 to facilitate integration with mobile applications.
I am using the Oauth2 authentication library that is packaged together with the Django Rest Framework.
To logout a user, I am expiring their access tokens, is this the correct way of doing things?
It's not correct. Normally, the access token expires when it reaches its expiration time.
Or in some these cases:
1. User revoke this access token.
2. Users change their password.
3. When refresh token is revoked, its issued access tokens will be deleted.
And here is a reference about log out.
I think what you mean is that you are creating a oauth2 provider?
If I am correct I would recommend switching to using token authentication. To create a oauth2 provider there are many restrictions and rules to follow and I assume when you create a oauth2 provider that it will be a public system that can be used by many people (that can and will misuse your service if it's has leaks)