Where to get Gitlab's OpenID ID Token? - oauth-2.0

Using Gitlab provided access tokens for the OpenID scope, i.e.
https://gitlab.com/oauth/userinfo?access_token=<bearer token>
returns a limited amount of information e.g. username, groups, etc. However, it does not return the user's email address.
The Gitlab documentation indicates that:
The claims sub, sub_legacy, email and email_verified are included in
the ID token, all other claims are available from the /oauth/userinfo
endpoint used by OIDC clients.
Given the AccessToken - how do I retrieve the ID token?
*This is a known / discussed issue cf. here

It all depends on what scopes you ask for when you first send the initial authentication request to GitLab.
You need to ask for the email scope to get that information back and you should get the ID-token back at the same time as you get your first access-token.

When you obtain code through authorization request, you need to specify the scope, and the scope needs to include openid,read_user,profile,email.
When exchanging the token with the code obtained in the first step, you can return to access_token and id_token.
When the access_token obtained in the second step is used to obtain the user information, it can return the user's e-mail.
Refer to the explanation of the scope used above:
openid: Grants permission to authenticate with GitLab using OpenID Connect. Also gives read-only access to the user's profile and group memberships.
read_user: Grants read-only access to the authenticated user's profile through the /user API endpoint, which includes username, public email, and full name. Also grants access to read-only API endpoints under /users.
profile: Grants read-only access to the user's profile data using OpenID Connect.
email: Grants read-only access to the user's primary email address using OpenID Connect.

Related

Asking for User Name or Unique Identity before OAUTH/OpenID-Connect

I am building a website that uses OAuth2.0 and OpenId-Connect (of some third party vendor) to authenticate user.
Before redirecting the user to the vendor's OAuth page, I am not asking the user to enter a unique UserID on my website, I was thinking of using the user's emailid that I receive as a part of IDToken after the Authorization process is done, as the user's User Name(unique identity) for my Website.
But the OpenID specification here
https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
says that emailid is optional and may not be returned.
So the questions is, is it a standard practice to ask the User to provide with a unique name (that I can use as user's identity on my website), before I initiate the OAUTH/OpenID-Connect process?
The sub claim must be unique per issuer. Required Claims will always be present. You can use the iss + sub to uniquely identify users.
To add more information, every OpenID connect provider need to provide a /userinfo endpoint to fetch the users information using access token.
here is the specification
https://openid.net/specs/openid-connect-core-1_0.html#UserInfo

OAuth2 Roles in OIDC

In OAuth2 protocol, Client (RP in terms of OIDC) application obtains an access token, which enables it to use different services (Resource server role) on behalf of a Resource Owner.
On the other hand, in the OpenID Connect protocol, Client obtains 2 tokens (access and id token). Now this Client can use the access token to fetch user claims from the UserInfo endpoint.
Does OP (Authorization server) play role of a Resource Server here (in terms of OAuth2), and Client fetches user data on behalf of a user?
How is ID token used by the Client? Does Client pass this ID token to the Resource Owner's user agent (Browser) and then, user agent stores this token to enable SSO (cookie)?
Does Client (e.g. different one than the one that obtained the ID token) has to verify the token every time user accesses it (call OP to verify it), or Client does this only first time it gets accessed by this token and then creates security context which enables it to eliminate this request for verification at OP every time? In this case, how could this security context be implemented?
What is the access token used for, except for fetching user claims and why is it sent along with ID token, when Client could use ID token to access UserInfo endoint?
First of all you must understand the purpose of tokens. Access token is a token that is good enough to access a protected resource on behalf of the end user. It is defined by OAuth 2.0 authorization framework. Now having an access token does not authenticate the end user. it simply authorize the client application to access a resource. OpenID Connect introduce the ID Token. Now this token is to be consumed by your client application. Protocol define how this to be done and if valid, your client application can authenticate the end user.
Q: Does OP (Authorization server) play role of a Resource Server here (in terms of OAuth2), and Client fetches user data on behalf of a user?
Partially correct. According to the protocol document, userinfo endpoint acts as OAuth 2.0 protected resource.
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User. To obtain the requested Claims about the End-User, the Client makes a request to the UserInfo Endpoint using an Access Token obtained through OpenID Connect Authentication.
Q: How is ID token used by the Client? Does Client pass this ID token to the Resource Owner's user agent (Browser) and then, user agent stores this token to enable SSO (cookie)?
As mentioned previously client must validate the id token and based on that it can authenticate the end user. ID token is not connected with SSO.
Q:Does Client (e.g. different one than the one that obtained the ID token) has to verify the token every time user accesses it (call OP to verify it), or Client does this only first time it gets accessed by this token and then creates security context which enables it to eliminate this request for verification at OP every time? In this case, how could this security context be implemented?
If you are using ID token to be consumed from a protected endpoint, then token receiving party should validate it before accepting it. One may choose to create a session after a proper token validation (session must not extend the life time of the token).
Q: What is the access token used for, except for fetching user claims and why is it sent along with access token, when Client could use ID token to access UserInfo endoint?
Access token is the token your should use to access OAuth 2.0 protected resources. Once the endpoint received it, endpoint can validate the access token against token introspection endpoint exposed by the authorization server (Protocol definition of introspection). And with Openid Connect, defining of userinfo endpoint let any party with valid id token to consume it.
I don't see how you can be confused about that if you've read the RFCs.
You want to think of identity as a "resource" service? fine, but the authentication for this service is different than for RPs, so what's your point?
The Client exists in the User Agent (we're talking about SPAs, right?). If the ID token is in the Client, then it's in the UA (the reverse is not true). If you're thinking of server-side clients, then there is no need to forward the ID token to the UA, unless you want the UA to pass it on to another Client (e.g. for SSO). There are SSO schemes that use the ID token for convenience, but that's not the stated purpose of the ID token.
The whole point of JWS is that you don't need to call the OP to verify a token. You just verify the signature. That may be done by any Client, whether they're the original recipient of a token, or they get it later. Furthermore, the ID token is not meant to authenticate the user. Using it for SSO requires some other form of security, such as storing a related secret in an HTTP-only cookie that will not be seen by the Client. Anyway, even if you use the ID token for SSO, then the ID token is sent only in the login request. After that, the Client will get its own access token for authentication and will not use the ID token again.
The access token is typically short-lived (which means the Client has to contact the OP regularly, which allows the OP a chance to revoke access). The access token is sent with every authenticated request, so it should be small (i.e. not contain user information that is not useful for authentication).

How are access tokens distinguished between resource providers in OpenID Connect?

I am working on creating an OpenID Connect (OIDC) Provider based around django-oidc-provider. I have been reading up on the OpenID Connect Spec, and I cannot figure out how access tokens are unique for a certain application.
Consider the following example with a user, Bob:
Bob wants to login to application A, so he goes to its interface and is redirected to the OIDC Provider. After authentication he is redirected (implicit flow) back to Application A with an ID token and an access token. He then makes a request at "/image/1" to A's API with his access token. The API uses the access token to reach out to the OIDC Provider to assert the user's identity as Bob. The API then returns the data at "/image/1" for user Bob, assuming that info exists. Bob continues to send his access token to A's API for any subsequent requests.
Then, Bob decides he wants to access application B's API. He sends B's API the same access token that he used with A's API. B's API reaches out to the OIDC Provider with the token and asserts the user's identity as Bob. B's API then returns the requested info for Bob.
What prevents this from happening? I see at least two possible solutions to this:
When reaching out to Google's token validation endpoint the "aud" parameter is returned. Application B's API would have to check this parameter to decide that the token is not valid for it's own API?
An additional scope must be added when requesting the token that is specific to the resource provider say "app-A-api". Then when an API is validating a token, the API would ensure the token contains the needed scope.
Which of these methods, or others, are in line with the OIDC spec?
If one of the above should be used, am I correct in assuming I should add a new /tokeninfo endpoint that returns the scope or aud, rather than add that info to the info returned at the /userinfo endpoint?
Any input is appreciated. I think a lot of my confusion comes from not seeing the "scope" param being used to delegate access to a resource provider in any OIDC examples.
I think the thing you are missing is that the application A and its API are two separate applications. So the tokens are issued for the application A. If the app-A-api uses the access token just for the user authentication, it's better to use an ID token - it can be validated without accessing the OAuth2 server. In this scenario, the app-A-api manages its user permissions by itself.
If the app-A-api needs the token to get a list of scopes (permissions) of its client, then use the access token. But in this scenario, the app-A-api (and app-B-api) are just accepting the access token - they are not the target audience (aud attribute) of the token. The application A is the audience of the tokens.
The APIs just check whether the access token contains scopes relevant for them. They trust the token issuer and it's up to the users to decide whether they trust the application A to perform actions on their behalf.
As an example, if a JavaScript application C (app-C) uses just Google Drive and Google Plus for its actions, then app-C will ask its user for an access token with scopes belonging to Google Drive and Google Plus. It will be just one token and both Google APIs will accept it.
And about the tokeninfo endpoint, it has it's own RFC called OAuth 2.0 Token Introspection, so you can check it.

get separate access token for a particular user in wso2 IS

I have created Service Provider and wso2 IS successfully integrated with LDAP, tested API and able to generate access token for user.
The wso2 IS generates same access token every time for a single user, even if i hit /oauth2/token api multiple times, Is it possible in wso2 IS to
generate separate access token for same user everytime i call /oauth2/token
wso2 IS able to handle this type of token management
Thanks
WSO2 IS generates a unique access token for the combination of
1. OAuth2.0 client ID (client/application)
2. Authorized user (resource owner)
3. Approved scopes (for the unique set)
If a valid access token already exists for the above combination in ACTIVE state that token will be returned. If you need a new token one of the above parameters MUST change.
A new feature JIRA has already been captured with regard to this:
https://wso2.org/jira/browse/IDENTITY-4404

Get a Unique OAuth token API from the WSO2 Identity Server

Our Mobile Client App uses https://identityserver:port/oauth2/token service from Identity Server by passing the ClientID and ClientSecret with grant_type as “client_credentials” to generate the access token. The generated access token is used to invoke the API from ESB.
As per the implementation the ClientID and ClientSecret will be stored in the device.
For an example, ClientX requested for an Oauth Token which will have a certain expiry time. Can this token make as a unique for ClientX?
Currently all the upcoming client calls will get the same access token as its already generated from the request of ClientX. If a client is requesting a token very late it will get the same token with almost expiry time.
Is there a way to make this token unique for the Client?
In your case, if you use “client_credentials” as a grant type, resource owner is also the client.
Since this is a mobile application, once your mobile app gets the token it will be used until the expiry date and there will not be a necessity of changing it, because of mobile is belongs to a single user. Therefore the token would be same for same scope till it is expired.
Ex: BBC news mobile application.
If you need different access tokens, you need to use different scopes.
You will need different access token in case if different clients accessing the same API. In that case you may use “PASSWORD” grant type for a unique access token.
Ex: Purchasing a product using ebay.
So you should define your scope properly to identify the use of access token.
Find the following blog that will help you to guide to select your scope. [1]
[1] http://wso2.com/library/articles/2014/02/securing-your-web-service-with-oauth2-using-wso2-identity-server-1/
I will assume that mobile application instance is bound per user.
If you want to get different access tokens for every user bound to a session don't use client_credential grant type.
For example you have client-x and client-y both using client_credentials grant. Identity Server (Authorization Server) will give an access token for client-x and client-y since this is about authorizing client-x and client-y to access resource and not about authorizing a user. This means whatever user you have in client-x or client-y requesting access_token, they can get one (assuming they are authenticated).Vice versa, a user, even if authenticated both client and identity server cannot get an access token if the request comes from client-z (client-z is not registered in identity server)
If your Oauth 2.0 client is browser-based you can use implicit grant, if it is a server you can use either authorization grant or resource owner password credential.

Resources