What all these fields mean? - oauth

When doing cross platform authentication, you can get an ID token from your Android app using the GoogleApiClient, which you can give to your backend server. The server will then first verify the token using the following url:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
If the token is properly signed and the iss and exp claims have the expected values, you will get a HTTP 200 response, where the body contains the JSON-formatted ID token claims. Here's an example response:
{
"iss": "https://accounts.google.com",
"sub": "110169484474386276334",
"azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"email": "billd1600#gmail.com",
"at_hash": "X_B3Z3Fi4udZ2mf75RWo3w",
"email_verified": "true",
"aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"iat": "1433978353",
"exp": "1433981953"
}
What does all these fields mean aside from email?

Claims contains a set of name/value pairs
iss: The issuer of the token
sub: The subject of the token.An identifier for the user, unique among all Google accounts and never reused.
azp: The client_id of the authorized presenter.
at_hash: Access token hash. Provides validation that the access token is tied to the identity token.
email_verified: True if the user's e-mail address has been verified; otherwise false.
aud: Identifies the audience that this ID token is intended for. It must be one of the OAuth 2.0 client IDs of your application.
iat: The time the ID token was issued, represented in Unix time (integer seconds).
exp: The time the ID token expires, represented in Unix time (integer seconds).
See: https://developers.google.com/identity/protocols/OpenIDConnect
for more details.

Related

Customize Oauth2+JWT token response with spring boot

I am using Oauth2+JWT+Spring security in one of my project. When i hit /outh/token using username/password i am receiving access token in the response with other details like
{
"access_token": <token>,
"token_type": <type>,
"refresh_token": <refresh-token>,
"expires_in":<secs>,
"scope": <scope>,
"jti": <value>
}
Is it possible to customize this response like
{
data: {
"access_token": <token>,
"token_type": <type>,
"refresh_token": <refresh-token>,
"expires_in":<secs>,
"scope": <scope>,
"jti": <value>
},
details:{
//extra information
}
}
I'm confused, don't know how to ask more clearly: "what is the additional data you want to send?". Just give an explicit sample.
I'll answer guessing that this data is related to the authorized entity (the user when answering within authorization-code flow and the client within client-credentials flow): non standard data should be set as private-claims, inside the JWT itself and on token introspection endpoint.
How to add such private claims depends on your authorization-server. For spring-security one, this is done with an OAuth2TokenCustomizer. For Keycloak, you have to provide a "mapper", etc.
The client which received a payload like the one you show, will only send the access-token when issuing requests to resource-server(s). It is important that this token holds all of the data needed for resources access decisions. Some claims are specified by OAuth2, OpenID defines some more standard claims, and you are free to put whatever additional data in private claims (within the limits of the maximum token size).
Also, if your client needs to read claims, it should use ID token, not access-token (request openid scope when initiating OAuth2 flow). Access-token should be interpreted by resource-server only.

Outlook Oauth .default suffix error trying smtp and imap after getting token

Im trying to access an Outlook email using Oauth , Already set this permissions on Azure App:
So, using Oauth 2.0 client credentials grant I obtain the access Token:
But, when I try to authenticate with that token it fails, so I read that it was necessary to generate a second token call using that first one as a parameter and using imap and smtp scopes concatenated, and I tried like in the examples:
And as you see, I get this suffix error :
{
"error": "invalid_scope",
"error_description": "AADSTS1002012: The provided value for scope https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send
is not valid. Client credential flows must have a
scope value with /.default suffixed to the resource identifier (application ID URI).\r\nTrace ID: 41d2086b-f83e-41d8-b405-115249b27901\r\nCorrelation ID: 6afef855-3fc9-4259-864b-4ec8e293e9d0\r\nTimestamp: 2022-04-29 00:02:06Z",
"error_codes": [
1002012
],
"timestamp": "2022-04-29 00:02:06Z",
"trace_id": "41d2086b-f83e-41d8-b405-115249b27901",
"correlation_id": "6afef855-3fc9-4259-864b-4ec8e293e9d0"
}
Any idea what am I doing wrong ?, why the first token its not enough or how do I get the access one in the second call ?
Thanks in advance !!

How to reduce the size of the access/refresh tokens in Keycloak?

I am setting a keycloack authentication server to allow authorized users to access a protected resource (OAuth2.0).
The access will be done from an embedded device that has certain restrictions. The main restriction is that the access and refresh tokens cannot be saved if they are longer than 256 characters.
While in The OAuth 2.0 Authorization Framework is silent about the token size, all the identity providers are free to decide about the token size. For example, Facebook's token is less than 256 bytes, the same for Google. But for keycloack, I get a token around 850 bytes! I have tried several encryption algorithms available in the admin console by I still get a large jwt token.
Decoding that jwt gives the following:
{
"jti": "d654564qsd-5fqsdf5-4qsdf-8b25qs-b556456",
"exp": 1556284611,
"nbf": 0,
"iat": 1556270211,
"iss": "http://myadress:myport/auth/realms/myrealm",
"aud": "myapp",
"sub": "45464-445645-4b45641e-456456-45645646",
"typ": "Bearer",
"azp": "myapp",
"auth_time": 1556269490,
"session_state": "cb95519c-0bf8-4b6b-94e4-a10d9000dbd2",
"acr": "0",
"allowed-origins": [],
"realm_access": {
"roles": [
"user"
]
},
"resource_access": {},
"scope": "readwrite"
}
I am actually not interested at all in the data in the tokens and I am not parsing it. I just need the token to be able to access the resource.
Hence, is there a way to reduce the size of the token to less than 256? if no, what is the best result I can get?
Thank you in advance
Also try to change signing algorithm. RSA256 ~354 symbols, ESA256 - 86 symbols, HS256 - 43 symbols. Could be configured using realm -> token -> default token algorithm or on client page
One aspect of the token size are the roles. If you don't need the roles to be in the token because you don't care about roles or you query the roles differently (eg. direct access via admin api), then use client scopes to remove the unnecessary roles. I know this may not be what u wanted to hear but it may help some people to get their token below 1 kB ;)
Tip: You don't need to create a 'Client Scope'. Its enough to enable specific Scope in the Client config tab and leave it empty: Keycloak Admin UI > Client > Tab: Scope > Disable: Full Scope Allowed

Access Token contains almost all information from Identity Token

The tokens below are returned upon initial token request with Azure AD B2C. access_token contains most information that id_token contains.
My questions are that:
1 Since access_token contains most information that id_token contains, what scenario can access_token be used in place of id_token? what scenario must id_token be used instead of access_token?
2 What are the rules regarding use of both access_token and id_token in general?
Result upon initial token request
{
"access_token": "access_token",
"token_type": "Bearer",
"expires_in": "3600",
"refresh_token": "refresh_token",
"id_token": "id_token"
}
Below is the decoded token for the respective token:
Please note that access_token contains most information from id_token, including user information.
access_token
{
"iss": "url",
"exp": 1550539339,
"nbf": 1550535739,
"aud": "audience ",
"idp": "LocalAccount",
"sub": "guid",
"name": "user#email.com",
"emails": [
"user#email.com"
],
"tfp": "B2C_1_ROPC_Auth",
"ver": "1.0",
"iat": 1550535739,
"azp": "guid"
}
id_token
{
"iss": "url",
"exp": 1550539339,
"nbf": 1550535739,
"aud": "audience ",
"idp": "LocalAccount",
"sub": "guid",
"name": "user#email.com",
"emails": [
"user#email.com"
],
"tfp": "B2C_1_ROPC_Auth",
"ver": "1.0",
"iat": 1550535739,
"auth_time": 1550535739,
"at_hash": "access_token hash"
}
Update
Further to question 1 above:
Since access_token contains most information that id_token contains, can access_token be used instead of id_token? That is, when id_token must be used instead of access_token?
I will take google as a example,
1) let say you want to implement social login where u mostly need fields like email, 'first_name', 'last_name'., these fields are mostly available in id_token. so id_token is perfect suitable for authentication.
2) later u need to fetch google contacts of the login user., In such scenarios u can't get contacts of the user in id_token. this is where access_token comes, though u won't have the contacts in access_token but all permission to fetch the contacts.
An ID token is intended for authentication. It is represented as a JSON Web Token (JWT) that contains claims about an authentication event including the identity information for a resource owner. The ID token is intended for a client application (a single-page app) and its aud (audience) claim contains the OAuth 2.0 client_id of the client application.
An access token is intended for access by clients to resources that are owned by a resource owner. It is represented as either a JWT (e.g. Azure AD B2C represents an access token as a JWT) or an opaque token. The access token is intended for a resource application (e.g. an API app) and its aud claim contains the OAuth 2.0 client_id of the resource application.

kid not matching on OAuth 2.0 flow

I'm using Okta for identity management. As the client in authorization flow, I send an authorize request to Okta. This works successfully, and I get a JWT payload. I want to verify the JWT signature, so I make another call to Okta in order to fetch the keys. However, the key ids (kids) do not match and verification fails.
Initial authorize request:
https://{{site}}.okta.com/oauth2/v1/authorize
?scope=openid
&response_type=id_token
&client_id={{client_id}}
&redirect_uri={{redirect_url}}
&nonce=4euiv0v52at3la15e7qlu1mt43
&state=7c92bqulrmdk2jk0ro9rd3mf5j
Response is a 403, redirecting me to:
{{redirect_url}}/id_token={{id_token}}
The header of the id_token is decoded into:
{
"alg": "RS256",
"kid": "2YKtkekCjCRWN0YqGsjUrNwIQaxGg5ahfHW0_fK8t64"
}
So far so good. I know that the authorization has succeeded. Time to validate the JWT.
However, when this is followed up with:
https://{{site}}.okta.com/oauth2/v1/keys
Or
https://{{site}}.okta.com/oauth2/v1/keys?clientId={{client_id}}
(they both return the same response), I get back this:
{
"keys": [
{
"alg": "RS256",
"e": "AQAB",
"n": "gv1rI9A7mrOoViJZTzUfiZl7YdEzLEofvRoVbXCgeW7aOmoKcAkWGHvqNRGoFgi8auV5b_TSgTXKq_TV1fz643hpAtba3V0Uw2lXchTbqXpmVRYXI1t4FIwRMXLe4Q-kcvp9la21e3D1lszjdPbFNX5GLAhrCW0Thu2HYbTLg6TbDTMaiQCMo15hek0JgZqRGzCkt9kINnwPVLXV_bkSh_fHWo_6G1L0MKYYQcgE6zvPlULLek98-yZ6Nlg6nJUY9nHn0qjhzqqq-bz_Vin8qi3Bt7SjUKwk7HbaugM84AEgDxYE5JgsaALIl5SgIc3GgFEc69qKWymoD-w1a8f1HQ",
"kid": "SOxFkBSLWefjlZoDI49Hk0nqlYtC28cjhTlVAYEzAxs",
"kty": "RSA",
"use": "sig"
}
]
}
Where the kid does not match what I received in the original response.
Where is my mistake?
You need to create an authorization server and use it as the endpoint, for example:
https://{{site}}.okta.com/oauth2/{authorizationServerId}/v1/authorize
You should also be able to use the default one:
https://{{site}}.okta.com/oauth2/default/v1/authorize
Note that this is different than the route you were using (which does not specify an authorization server):
https://{{site}}.okta.com/oauth2/v1/authorize
You should specify an authorization server in your case (like example 1 and 2 above), for both OAuth 2.0 and OpenID Connect.
The problem was that this account was setup with pinned, not rotating keys. oauth2/v1/keys requires the client id to be passed in as a parameter if you are setup with pinned keys; the correct parameter name is "client_id", not "clientId." This results in the expected output.

Resources