I use [JWT for Client Authentication][1] in [Keycloak][2]:
POST /token.oauth2 HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=vAZEIHjQTHuGgaSvyW9hO0RpusLzkvTOww3trZBxZpo&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3A
client-assertion-type%3Ajwt-bearer&
client_assertion=eyJhbGciOiJSUzI1NiJ9.
eyJpc3Mi[...omitted for brevity...].
cC4hiUPo[...omitted for brevity...]
I get :
assess_token
refresh_token
token_type
expires_in
When I try to refresh token I send refresh_token itself, grant type refresh_token and get:
"error": "unauthorized_client",
"error_description": "INVALID_CREDENTIALS: Invalid client credentials"
}```
when I specify `client_id` I get:
```{
"error": "invalid_client",
"error_description": "Parameter client_assertion_type is missing"
}```
If I specify `client_assertion_type` I get error that `client_assertion` itself is missing, so I literally have to provide parameters I provided when retrieved access token.
How that refreshing process actually should work?
[1]: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-jwt-bearer-12#section-2.2
[2]: https://www.keycloak.org
This could very well be a limitation or policy defined by Keycloak. RFC7523 (JWT for Client Authentication) does allow to enable client credentials when JWT authentication is present. This is highlighted from 3.1. Authorization Grant Processing
JWT authorization grants may be used with or without client
authentication or identification. Whether or not client
authentication is needed in conjunction with a JWT authorization
grant, as well as the supported types of client authentication, are
policy decisions at the discretion of the authorization server.
However, if client credentials are present in the request, the
authorization server MUST validate them.
So even if Keycloak support JWT client authentication, it may still require client credentials to be present in the refresh token request. But also, it could be a limitation from their end.
Additionally, token refresh is defined through RFC6749 - The OAuth 2.0 Authorization Framework. According to it's section 6, refresh token request must contain client credentials when client is a confidential client (simply a client which was created with id and a password). If what you seen is not a limitation, then guess Keycloak adhere to RFC6749 and require you to send client credentials in token refresh request.
Related
I aim to fetch purchases from googleapis by using a service account on server-side.
Method: purchases.products.get api requires an oauth2 authentication.
Therefore I create an oauth2 token -from the client-secret.json I am provided from consolce.cloud.google- inside of my server-side backend java spring application.
GoogleCredentials googleCredentials = GoogleCredentials.fromStream(new FileInputStream("src/main/resources/client_secret.json")).createScoped("https://www.googleapis.com/auth/androidpublisher");
googleCredentials.refresh();
AccessToken accessToken = googleCredentials.getAccessToken();
The token I generate is like 'ya29.c.b0AXczHcuLszNI................'
It ends with multiple dots I don't know why.
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}
After I get the token I do the GET request to this URL.
I gets the following error:
"message": "Request is missing required authentication credential.
Expected OAuth 2 access token, login cookie or other valid
authentication credential. See
https://developers.google.com/identity/sign-in/web/devconsole-project.",
Why my token is not working? The way I use it, Is it wrong? And/or oauth2 token generation way is it wrong?
The access token is sent as an authorization header. The access token should be prefexed with the term bearer as it is a bearer token.
If you request a token from the server (with the same credentials and within the lifespan of an old token) should it either:
return a fresh token every time
return the same token with a shorter lifespan
something else / depends on
Is it depending on whether you use a refresh token?
Can you please reference the OAuth 2 RFC in your answer ?
The OAuth 2.0 Authorization Framework is a framework that allow a Resource Owner to CONSENT to allow DELEGATION of their permissions to access a Resource Server to another party (OAuth Client).
The Authorization Request is performed by the OAuth Client and is fulfilled by the Authorization Server only after obtaining CONSENT from the Resource Owner by the Authorization Response (which includes a Access Token).
The Access Token is a Bearer Token with a limited lifetime.
The refresh Token, if used, by the client to requests a new access token by authenticating with the authorization server and presenting the refresh token. The client authentication requirements are based on the client type and on the authorization server policies.
The "same" Access Token is never returned or reused by the Authorization Server.
Reading and following the Security Considerations with any Authentication or Authorization Protocols is a must. Most breaches are caused by implementation errors rather than protocol errors.
You should Tell us what you have tried and show logs or results and Read:
https://stackoverflow.com/help/how-to-ask
The Scenario
I've recently built an API, and have protected its resources using OAuth Bearer Access Tokens.
I've used the Client_Credentials Flow, as it will be accessed by clients as opposed to users.
Here's the thing, when a client has successfully provided the client_id and the client_secret they receive a response like the following :-
{
"access_token": "<Access Token>",
"token_type": "bearer",
"expires_in": 1199,
"refresh_token": "<Refresh Token>"
}
Refresh Tokens.
Not knowing much about refresh tokens, i immediately assumed that a client would be able to provide the OAuth Server the refresh_token to retrieve a fresh Access_Token.
This is 'kind of' correct.
In order to use the refresh_token the client still needs to pass the client_id and client_secret along with the refresh_token to get a new access token.
The grant_type also needs to be changed to refresh_token.
Where is the benefit of a refresh_token using this flow? If I need to pass the client_id and client_secret each time, surely you would just avoid using a refresh token altogether?
The issuance of a refresh token with the client credential grant has no benefit.
That is why the RFC6749 section 4.4.3 indicates A refresh token SHOULD NOT be included. Thus its issuance is at the discretion of the authorization server.
From my point of view an authorization server should never issue a refresh token with the client credentials grant as the access token issuance process will take an additional and unnecessary step:
The issuance of he access token with the client_credentials grant type is done on the first request.
The issuance of he access token with the refresh_token grant type is done after at least two requests, depending on the way you issued to first access token.
The benefit is that he request token normally has a much longer life span than the access token.
Access token is used in communicating with the resource server.
Request token is used when communicating with the authorization server.
You could read this as that you may be authorized but that the exact extend of your authorization needs to be reevaluated from time to time. So request token has it use.
I'm trying to understand both OAuth 2.0 and OpenID Connect and i have an important question: How OpenID Connect Endpoints communicate with each other ?
Example : In case of an Authorization Code Flow, if The Authorization EndPoint gives an access_token to the Client, this one will send this token to UserInfo Endpoint to get User Information.
So the question here is, how UserInfo Endpoint can verify that the access_token issued bu the Client is the right one ? is there in ommunication between those two endpoints ?
Thanks for answering.
UserInfo Endpoint must be able to interpret access tokens issued from Authorization Endpoint or Token Endpoint.
In a simple implementation, all the endpoints are implemented on one server. In this case, UserInfo Endpoint can get information about access tokens easily only by referring to the same database table storing access tokens issued by Authorization Endpoint or Token Endpoint.
On the other hand, if Authorization Endpoint and Token Endpoint are implemented on an authorization server and UserInfo Endpoint is implemented on a resource server, the resource server must inquire of the authorization server to get information about access tokens. RFC 7662 (OAuth 2.0 Token Introspection) is the standard defining how to get information about an access token from an authorization server.
RFC 7662 is the standard for token introspection, but implementers of authorization/resource servers do not necessarily have strong motivation to support the specification. See "4. Introspect Access Token" if you are interested in why.
BTW, in Authorization Code Flow, an access token is issued not from Authorization Endpoint but from Token Endpoint. What is issued from Authorization Endpoint in the flow is an authorization code (not an access token).
After reading the Google OAuth2 documents, I have downloaded the application_default_credentials.json and used this to get access token(bearer token).
I'm not sure if this's the standard of OAuth2. Some documents show that we need refresh token and client credential to get access token, but why not just refresh token? If I have client credential, does that mean I can get access token directly?
Yes, it is part of the OAuth2 specification that you must send the client credentials along with the refresh token. From RFC 6749, section 6:
Because refresh tokens are typically long-lasting credentials used to request additional access tokens, the refresh token is bound to the client to which it was issued. If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server.