How to create client_assertion and assertion in on_behalf_of flow - azure

I want to get access token with a certificate.
I know values of these client_id, grant_type, scope from my application.
But where can I find values of assertion and client_assertion.
Do I need to get more tokens, I'm completely lost here.
Can anyone guide me with working example?

This is a sample. It can be summarized as:
go to this url to get auth code:
https://login.microsoftonline.com/tenant_id/oauth2/v2.0/authorize?
client_id=aad_client_id
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=api://aad_client_id_which_exposed_api/permission_name
&state=12345
2.use auth code to generate access token by auth code flow.
3. use access token to generate another access token by obo flow.
On behalf flow is used when an API want to call another API. So at first you need to have a web api which is protected by AAD, so that it can receive an access token A. After having this token A, on behalf flow can generate a new token B by A, so A is the value for parameter assertion. Then using client id + client secret and follow this section to generate access token by obo flow. And this is what I do in the screenshot.
Azure AD also also us to use certificate rather than client secret to complete the authorization. So we can also follow this section to do it. As you can see, missing client_secret but appear client_assertion_type client_assertion.
Then the only issue left is how to get the token A. Just like what I say, token A is used for visiting API which is protected by AAD, so you need to expose an API and give the api permission, then update your project to authorize the scope right? Then this tutorial demonstrate the whole progress. Finished all the steps, then you may need to sign in with your onmicrosoft.com account first, then you can get a code from the url in the browser, then use that code to generate an access token, this token should had scope like api://aad_client_id/xxx, and this is token A.
You may also refer to this tutorial, this can help you understand obo flow.

Related

Azure access_token contains info that I thought would be in the id_token, and vice-versa

When requesting a token and id_token from Azure using the implicit grant flow using a request like
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=token%20id_token
&redirect_uri=http%3A%2F%2Flocalhost
&scope=openid%20user.read
&response_mode=fragment
&state=12345
&nonce=678910
I'm successfully getting a response back with an "access_token", and an "id_token".
From what I've read, when decoding the "id_token" I should see information about the user (like name, email, picture, etc), and the "access_token" (should not be decoded) is what should be used to use as the "Bearer" token in the "Authorization" header.
When I view the token details with https://jwt.ms the "access_token" is the one with the user details, and the "id_token" has none.
When I try to access my API with the "access_token", it doesn't allow, but if I access it with the "id_token" it does.
This seems contradictory to the documentation so I'm wondering if someone can clarify for me?
You are right - the ID token is the one which gives your app information about the authenticated user, the access token is the one that you should use to access MS APIs. That said, please note the following.
When I view the token details with https://jwt.ms the "access_token" is the one with the user details, and the "id_token" has none.
What do you mean by "user details"? Usually the access token will contain some details about the user, which the APIs would need to perform proper authorization. Very often it will be the sub claim, but there might be some other claims as well. Note also that by default the ID token doesn't carry much information about the user either. You have to request other openID scopes, like profile or email to get more information about the user in the ID token. Here's the documentation of what claims you can find in the ID token, and which scopes should be requested to get these claims: https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens.
When I try to access my API with the "access_token", it doesn't allow, but if I access it with the "id_token" it does.
What do you mean by "my API"? Is it an API you created from scratch, or some API you deployed using Microsoft tools? Are you sure that your API is configured to be accessible with an access token from Microsoft? Usually that token would be used to access MS APIs, not your own.
Depending on how the authorization server is configured, the returned id-token might not contain that many user claims.
But how will the client get the missing information?
The client can then do a background request to the UserInfo endpoint to retrieve the additional claims and user information. by doing it in this way, the id-token size is reduced.

Does Azure Active Directory support the JWT bearer token flow?

We have a number of services that can be called by users via HTTP based protocols (SOAP/REST/WebDAV). The services support various authentication mechanisms (e.g. Basic, and OIDC Bearer tokens). Sometimes a service has to call another service without a live user. For that, we configure technical users, and service A can call B with the credentials of a technical user.
For OAuth/OIDC authentication via Bearer tokens, we use the JWT bearer token flow to acquire access tokens for our technical users: Service A creates a JWT with the name of the technical user and signs it with its own private key. It then calls the OIDC token endpoint with that token and receives an access token for its technical user X. It can then use this token as a bearer token to call service B, which will accept the token for user X. (For more information on the JWT bearer flow, cf. RFC 7523 section 2.1 and RFC 7521 section 4).
This works fine with our Connect2id test server and also with Salesforce, but we haven't been able to get it working with Azure. Accessing Azure's token endpoint always results in the following error response:
AADSTS50027: JWT token is invalid or malformed
According the Microsoft's documentation, this error can have any number of reasons:
doesn't contain nonce claim, sub claim
subject identifier mismatch
duplicate claim in idToken claims
unexpected issuer
unexpected audience
not within its valid time range
token format is not proper
External ID token from issuer failed signature verification.
When trying to find out more about Azure and the JWT bearer flow, the only solid information I've been able to locate is this article:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
It describes the "On-Behalf-Of" (OBO) flow, which as far as I understand is an extension (by Microsoft?) to the JWT bearer flow, adding a second JWT to the mix along with a parameter called "requested_token_use" set to "on_behalf_of". I can only find "requested_token_use" in relation to the special OBO flow, and its only value seems to be "on_behalf_of".
OBO flow isn't what we want, since it seems to allow a service X to turn a token received by service Y into another token, using the Y token and a self-generated X token to call the token endpoint. Our use case only has a self-generated X token and the name of the user who the app is permitted to impersonate.
After a lengthy trial & error phase we've come to the impression that OBO may in fact be the only (non-standard) version of the JWT bearer flow that Azure knows about, and that it may not support the "normal" JWT bearer flow we're trying to use at all. Is this correct, and we have no option but to give up trying to solve this scenario with standard OIDC when Azure is involved, or does Azure in fact also support the flow we've implemented and we're just doing something wrong (e.g. wrong audience or issuer in our JWT, or a mis-configured app in Azure)?
PS: Our code is written in Java and we use the Nimbus library for our OAuth/OIDC communication.

Login cognito using with scope openId using id_token or access_token don't working

I'm using cognito to authenticate to node-js using amazon-cognito-identity-js I logged in and it returns me an access_token, id_token and refresh_token but none of them work when I'm using the open id scope with authorization code grant.
I don't know if I need to call another service or do another process to get access at the gateway
but when I generate a token using client_credentials flow the api gateway works
If I understood correctly, the scopes you are setting are OAuth 2.0 scopes and require using the OAuth 2.0 endpoints (e.g. the hosted UI, or an external IdP federation). Your code seems to be using the non OAuth 2.0 flow (e.g. I assume InitiateAuth with SRP). If you decode the JWT I believe you will see it has only the aws.cognito.signin.user.admin scope.
For using custom scopes you will need to
send the access token (not the id token)
use token you got from the token endpoint (e.g. using the hosted UI or federation) - they will contain the scopes you set in the screenshot
For using the open_id scope, same as above but send the id token, not the access token, and remove the custom OAuth scopes in API Gateway (if you put them it will expect an access token)
p.s. custom scopes work great with the client credentials flow, but less with the authorization code flow if it doesn't have a client secret.
Lastly I recommend you take a look at AWS Amplify as it will handle a lot of that for you behind the scenes as well as include security features such as PKCE out of the box.
Relevant github issue: https://github.com/aws-amplify/amplify-js/issues/3732

OAuth authentication authorization

i am totally confused about the usage of OAuth and i am not sure how to use oauth for my szenario. At the moment i use a "pure" JWT approach which looks like that:
Client (JavaScript Application) send login and password to my Rest-Endpoint (Server (Java)).
Server validate user informationen, read / generate some user roles and wrap it in a JWT Token (with a secret)
Server send JWT Token back to client
Client will perform additional Rest-Calls with Authorizationen Header
Server validates Token with private secret and grand access based on roles/user
Now i think about the usage of OAuth but i am confused how to use it to realize the szenario.
I registered an application at "auth0".
I use a JS library to redirect to the login process of auth0, login via auth0 account and consume the id_token and access_token
= i can send the id_token (JWT with RSA256) to my rest api, validate it with the public certificate and can extract some user information
but:
a) i have read that i should not use the id_token to access my api. Instead i should use the access_token (which is not in JWT format and will not give me any information about the user) and use the access_token to query for the user information? That whould be the case for every request?!
b) i don't see the point where the user roles come into play. When i have some operations (rest endpoints) which are only allowed for "admins" or "customers". I don't see any possibility to define them.
You see i am a little bit confused, i hope somebody can clarify all the things.
Thanks a lot
Chris
a) Both tokens you use should be in JWT format and you should use access_token for authenticated queries. The access_token not necessarily contains information about the user, so on server side you usually can decide only that the token is emitted by the token service and is valid. If all these checks are passed, you should accept it as an authenticated user.
b) User roles can be placed into the access_token's payload section as an additive claim (e.g. role=admin,datawriter or role=customer,listreader) like many other things.
I hope it helps.
a) Sounds like you are getting an opaque access_token back and not a JWT. You'll need to create an API in Auth0 (similar to the application/client you already created). Then you pass that identifier in the audience parameter when you authenticate. Then you should get a JWT back, and that will have a sub parameter which is the Auth0 ID of the user, which can help you identify who the user is. I believe you could also use Auth0 rules if you need to put more identification info into the token. See here for a full explanation of the opaque vs. JWT access token: https://auth0.com/docs/tokens/access-token
b) Roles are tricky. I believe Auth0 would suggest that you create scopes on your API, and then request the scopes needed during login. Auth0 Rules would then be used as a sort of "glue", to adjust scopes that were requested but not permitted for the authenticated user. They also have an Authorization Extension you can use to help facilitate some of this. Another option could be storing role info in the user metadata, and using rules to put that info into the token. Finally, the option we chose was to not use Auth0 to define our roles. We let Auth0 authenticate, and once authenticated we check access in our system for the authorization side of things. Lots of options.

Understanding Oath 2.0 Autorization Code Flow

Why do we need first contact the Oath Auth endpoint to get an auth code, and then once we have received the auth code we need to contact the Oauth Auth endpoint again to get the access token so that we can call a webservice?
Why not just return the access token in the first step, after the user has signed in successfully?
Also, how does the webservice (API) then verify that the access token is legit?
Why do we need first contact the Oath Auth endpoint to get an auth code, and then once we have received the auth code we need to contact the Oauth Auth endpoint again to get the access token so that we can call a webservice?
So the web service (or Relying Party) never sees the user's credentials.
And because of how this flow works, the user also cannot see the application's credentials.
User also can't get the access token to use it themselves, though that actually would not matter that much.. Implicit Grant Flow actually does what you want, allowing you to get an access token directly from the authorization endpoint. But that is mainly for Single Page Apps, for which that is the easiest option.
Authorization Code Grant flow allows the app to use a stronger authentication via a client secret or certificate.
This is called an OAuth dance by the way :)
Why not just return the access token in the first step, after the user has signed in successfully?
See my mention above about Implicit Grant flow.
Also, how does the webservice (API) then verify that the access token is legit?
By checking the digital signature. Azure AD (and B2C) publish public keys for the key pairs they use for signing at a well known endpoint.
The authentication pieces in an app must check the JWT signature is valid by the defined public key.

Resources