We have an application registration on Azure AD to which users authenticate to by requesting their own access token:
{
"aud": "CLIENT_ID",
"iss": "https://login.microsoftonline.com/TENANT_ID/v2.0",
"iat": 1701270410,
"nbf": 1701270410,
"exp": 1701274744,
"aio": "AUQAu/8VAAAAHAdHfHVno15JVZNMHln+AtJiQ5c9jjw5ny4AfK+0gq8siK+6H8bxHnE40bQMa5+oH/oTRxuuy2F/mYdD8w7RyQ==",
"azp": "04b07795-8ddb-461a-bbee-02f9e1bf7b46",
"azpacr": "0",
"name": "USER_FULL_NAME",
"oid": "USER_OBJECT_ID",
"preferred_username": "USER_EMAIL_ADDRESS",
"rh": "0.ARcA9s6n4x-uDUih6CznvYX1DqJqF4JIEcZBhyJIsPIi-CwXAO0.",
"roles": [
"READ"
],
"scp": "read",
"sub": "SVfA-IJg9t-Z73Le-dad5EAOyq3QjwU1oS5csbOTbGI",
"tid": "TENANT_ID",
"uti": "vOTt0phu40yVrNAqqj8oAA",
"ver": "2.0"
}
Using this token, the app reg is able to authenticate and authorize the user to execute some code/logic associated to it.
Now we want to use OAUTH Token Exchange Protocol
so that our app registration can use the user's access token to request a new access token from Snowflake. I know that this is feasible with Oauth access tokens according to the following article:
https://www.scottbrady91.com/oauth/delegation-patterns-for-oauth-20
so basically one would do something similar to:
POST /token
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&client_id=OUR_APP_REG_CLIENT_ID
&client_secret=OUR_APP_REG_CLIENT_SECRET
&scope=api2
&subject_token=USER_ACCESS_TOKEN
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
but I am not sure if it is possible to achieve it with Snowflake. And if the token exchange protocol can be used with Snowflake; can somebody show us the steps to configure it and what are the other parameters that we have to provide during the POST
request? Thanks.
Using On Behalf Of
documentation, I was able to achieve what looks like token exchange using this query:
curl.exe -X POST -H "Content-Type: application/x-www-form-urlencoded" -d
"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&client_id=
{CLIENT_ID}&client_secret={CLIENT_SECRET}&assertion=
{user_access_token}&scope=https://graph.microsoft.com/.default&requested_tok
en_use=on_behalf_of"
https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token
but when validating the token on jwt.io it says that the signature is invalid.
Note that, you will get "Invalid signature" error if you trying to validate the access token generated with Microsoft Graph scopes.
I registered one Azure AD application and added permissions of 2 exposed APIs along with Microsoft Graph API:
Now, I generated one user access token that have similar token claims as you like this:
When I ran your curl request in Postman with Microsoft Graph scope, I got access token in response:
curl.exe -X POST -H "Content-Type: application/x-www-form-urlencoded" -d
"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&client_id={CLIENT_ID}
&client_secret={CLIENT_SECRET}
&assertion={user_access_token}
&scope=https://graph.microsoft.com/.default
&requested_token_use=on_behalf_of"
https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token
Response:
There is no need to validate tokens generated with Microsoft Graph API scopes. If you validate it, it will throw "Invalid Signature" error.
You can directly call Microsoft Graph API using above access token without any validation:
GET https://graph.microsoft.com/v1.0/me
Response:
Alternatively, you can generate the token for other APIs that are meant for application.
In my case, I ran below curl request by replacing scope
with other exposed API value like this:
curl.exe -X POST -H "Content-Type: application/x-www-form-urlencoded" -d
"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&client_id={CLIENT_ID}
&client_secret={CLIENT_SECRET}
&assertion={user_access_token}
&scope= api://<API_appId>/test.read
&requested_token_use=on_behalf_of"
https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token
Response:
When I decoded this token in jwt.io, signature validated successfully as below: