Getting Security Groups in JWT Access Token - oauth

I would like a JWT access_token to contain a list of security group. From reading the documentation I attempted setting "groupMembershipClaims": "All", in the manifest of my application regostraton.
The setup is that I have a azure ad domain with 2 users. Then I have 2 groups: [user, admin] Each user has one of the groups assigned to it. Each group is of type security.
I am attempting to perform the OAuth Code flow manually, by going to the url formated similar to this:
https://login.microsoftonline.com/<tenantid>/oauth2/v2.0/authorize?client_id=<application-id>&response_type=code&redirect_uri=http://localhost:8080&response_mode=query&scope=offline_access%20user.read%20mail.read&state=12345
Then I login using the user account I setup in azure ad. Then I use postman to submit a post request to https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token with parameters:
client_id = <client-id>
code = code from previous login,
redirect_uri = http://localhost:8080
grant_type = authorization_code
scope = user.read mail.read
I get a valid response back, with an access_token. However when I decode it there is no group claim listed at all.
How can I get the groups listed in the token?

According to my research, Azure AD v2 endpoint of Azure Active Directory does not yet support groups claims in its token. For more details, please refer to the document. If you want to get all groups one user belongs to, you'll need query the groups from Microsoft Graph API. You can find the API documentation here:https://learn.microsoft.com/en-us/graph/api/user-list-memberof?view=graph-rest-1.0.

If you use the app to access own API, in order to get group claim in the access_token, you need to configure the groupMembershipClaims value as you want in the API manifest, then you could get the group claim information in the access_token.
But if the access resource is MS graph API or Azure AD graph API, you could not configure for them, you could only use the openid connect to get the id_token, and then you could see the group claim in the id_token. In your flow, you could add openid in the scope, then you could find the group information in the id_token.
I tried oauth2 code flow in the postman:
And it returns the access_token and id_token. To parse the id_token, I get the group information:

Related

Get list of keySets (policy keys) in a given Azure AD B2C tenant with Microsoft Graph API

I'm trying to figure out how to use Microsoft Graph API in order to get information on an Azure AD B2C tenant's Policy Keys. It seems like it should be possible given the following documentation, but I keep getting an InvalidAuthenticationToken error.
Documentation link: https://learn.microsoft.com/en-us/azure/active-directory-b2c/microsoft-graph-get-started?tabs=app-reg-ga
What exactly do I need to do to call the endpoint shown in here (the /trustFramework/keySets endpoint)? https://learn.microsoft.com/en-us/graph/api/trustframework-list-keysets?view=graph-rest-beta&tabs=http
In postman, I'm simply firing off the get request with Basic auth using my Portal credentials. Am I going about this the right way?
I tried to reproduce the same in my environment. and received similar error *InvalidAuthenticationToken*
Then , I checked that I missed to give authorization header with bearer token ,
Which Is required parameter to query that as per : List keySets - Microsoft Graph beta | Microsoft Learn
Below are the scopes , I have given admin consent to. delegated and application permissions like openid offline_access profile User.ReadWrite.All TrustFrameworkKeySet.Read.All Policy.ReadWrite.TrustFramework AuditLog.Read.All
Do a get request at https://login.microsoftonline.com/xxxxxx063/oauth2/v2.0/token to receive a token for the application endpoint in postman with the scope for graph i.e; https://graph.microsoft.com/.default , for that particular tenant (here used tenantId of azure ad b2c).
Give required values like client_id, client_secret for client_credential flow
Then try to query graph using that token :
GET https://graph.microsoft.com/beta/trustFramework/keySets ,
Following above steps with correct values and granting admin consent , I could successfully query the keySets

Get single token for Microsoft Graph API and Microsoft Dataverse Web API

I am using Microsoft Graph API and Microsoft Dataverse Web API in a single applications. Due to this, I have to get 2 different access tokens for each by addding different value of resource key. Is it possible to generate a single token that can be used for both ?
This might also be achieved through RefreshToken to get an AccessToken to the individual endpoints with the same scopes as authorized when you requested the graph access (scopes).
E.g. If you requested Mail.Read (https://graph.microsoft.com/mail.read) you can get back to the token issuing endpoint with the refresh_token with scope="https://outlook.office.com/mail.read" and get an accesss_token for this endpoint.
you can use the On-Behalf-Of Grant to exchange the token with a new one, only this time addressed for the resource you need. Please refer this Document.

Where to get Gitlab's OpenID ID Token?

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.

AWS Cognito - using scopes in authorizing access to api gateway

I have setup a Cognito user pool so that I can use it to authorize access the an api gateway. It uses OAUTH2 and the flow im using is : Authorization Code Grant,
Scopes : email, openid and profile,
Allowed Custom Scope : product-api/read_product, product-api/create_product, product-api/delete_product
I use boto3 admin_initiate_auth command to connect to the user pool:-
response = idpclient.admin_initiate_auth(
UserPoolId=USERPOOLID,
AuthFlow='ADMIN_NO_SRP_AUTH',
AuthParameters={
'USERNAME':USERNAME,
'PASSWORD':PASSWORD,
'SECRET_HASH':SECRET_HASH
},
ClientId=APPCLIENTID
)
and the response I receive is a json object with several fields, which include access_token, refresh_token etc...
but when I use the access_token to access the api gateway, i get a 401 error. Unauthorised. Looking into the access_token it looks like the custom scopes have not been added.
Could you advise why the custom scope has not been added to the access_token and how do i get the custom scopes added ?
the api gateway has a lambda authorizer added.
Usually you have to specify the Scopes in 2 places:
The OAuth client entry for the client application in the Cognito section of the AWS console
The code requesting a token - I have always implemented this in a standards based manner whereas you are using an AWS specific solution
Looks like what you want may not be supported via admin_initiate_oauth:
Include user details in AWS Cognito Oauth2 token
If your client application is a web UI then the standards based solution will do what you want.
I've tested my Cognito single page app sample with custom scopes - you can run it here:
https://authguidance.com/home/code-samples-quickstart
Not sure if this type of solution will work for you though ..

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.

Resources