Azure AD reply URLS and Client Credential Grant flow - azure

I have 2 services, let's say A and B configured as web apps in azure. B needs a JWT bearer token to return a value. So when we try to call B from A, we Include the JWT bearer token in HTTP call from A using the Client Credential Grant flow explained here: https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow
Now the AAD registration of service B doesn't have localhost as it's reply URL but I noticed that I was able to talk to it from localhost. So Does AAD not respect reply URLs in client credential grant flow?
My understanding of reply URLs is this:
“In the case of a web API or web application, the Reply URL is the location to which Azure AD will send the authentication response, including a token if the authentication was successful.”
I'm using AuthorizationContext.AcquireTokenAsync() method with client credentials of App A and resource id of App B. So It should not return me the token to localhost because it's not configured?

Now the AAD registration of service B doesn't have localhost as it's reply URL but I noticed that I was able to talk to it from localhost. So Does AAD not respect reply URLs in client credential grant flow?
No, reply URLs define the destinations where AAD can send tokens after user authenticates.
In client credentials flow the tokens are sent in a response to a request from a program.
So they do not matter.

Related

Can Bearer token validate Message Extension request from MS Teams?

I created a message extension for an App within Microsoft Teams that when clicked sends the message from Teams to my web service.
(one of these https://learn.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/how-to/action-commands/define-action-command)
I don't need to authenticate the user, but I want to authenticate that the incoming request came from Microsoft instead of someone maliciously sending me data.
The Authentication method described by Microsoft here; authenticates the user individually on the system. Which I don't want as the user might not have an account.
There is a Bearer token in the header of the action's incoming request to my web service. Can I somehow utilize this to validate it?
You shouldn't validate the Bearer token sent from MS Teams to your MS Teams App.
The right way to do it is use the "client credentials grant" between your MS Teams app and your web service. The grant is described here: https://www.rfc-editor.org/rfc/rfc6749#section-4.4
Your MS Teams App will be the client. Each request your client sends to your web service will contain a token issued by either your web service or an external identity provider your web service trusts. This token will be validated by your web service to ensure the request is genuine.
This grant is suitable for service-to-service communication you described.

Azure AD OAuth Client Credentials Grant flow

Trying to set up Azure AD OAuth client credentials grant flow for my web api. I'm following the document in https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow. I have to expose my API to a 3rd party. I've created the APP in Azure AD (this is for the client that is requesting my API), generated the secrets and was able to get a response from oauth2/token endpoint. My questions are below:
What is the best way to validate the token? Is it by passing the JWT
(bearer token) as a HTTP header to my API, and then using the SDK to
validate the token
(System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler)? I'm using
C#.
What is the significance of Azure AD -> App Registrations -> "My
API App" -> under Manage, Expose an API? It has an option to
"Authorize client applications". How could I use this feature to
conditionally block and approve the client applications?
I will have to share the secret, client id and the App Id Uri with the 3rd party for them to generate the token and I will validate the token when I receive it.
You're on the right track.
This answer, Azure AD OAuth client credentials grant flow with Web API AuthorizeAttribute Roles, will walk you through one way to do this, using the roles claim in the token to authorize the call.
You will need to:
define roles
create an App registration for each 3rd party
assign their application to your desired roles
You can then use the AuthorizeAttribute to map which roles can execute which controllers/actions, like so:
[Authorize(Roles = "Reader,Requester,Editor,Approver,Administrator")]
Token validation
Once you complete token obtaining flow, you receive a JWT bearer access token. From token consuming end (your service), you need to perform a JWT validation. This is done by validating JWT signature and Claims. One of the most important claim you validate is the audience (aud) claim which must be the identifier (ex:- your service's URL, an ID) unique to token receiving service. Where you register this ? That's your second question.
Please read through MS's guide on token validation which explains key points - Microsoft identity platform access tokens
Service registration
This is where you register valid token receivable endpoints (ex:- your api app). If you check your token request, you provide resource parameter which must match to registered identifier. This allows Azure to validate the token request and issue an access token the mentioned resource. You find this as aud claim in the token. Hope you got the connection now.
App secret
No, only the token obtaining party require the client credentials. Your API or any token consuming party does not need the secret. They only require a valid access token and token signing certificate details. certificate details are exposed at jwks_uri in openid-configuration endpoint.

How to generate oauth token for webapi without using client id and client secret

I have deployed one webapi into azure. After that I have register my API into Azure AD.
I got my API client-id and client-secret, now i just want to test my API not like
3rd application will access it so what will be recourse id in this case.
I have used oauth for authentication into that webapi.
I want to test that webapi so into POSTMAN i used this url to generate oauth token
which i will pass as header Authentication bearer token.
step 1 -
https://login.microsoftonline.com/{{OAuth_Tenant}}/oauth2/token
in header -
grant_type:client_credentials
client_id:{{client_id}} // i have my API client-id
client_secret:{{client_secret}} // i have my API client-secret
resource:{{resource}} // i have my API client-id
when i generate token using above values and send that bearer token it fail error unauthorized.
You need to register an app in Azure Active Directory to acquire access tokens.
Register an app there, and you can find the client id/application id there.
Then you can create a key for the app, that's your client secret.
Finally the resource should be the client id or app id URI for your API's app registration in Azure AD.
To implement this according to best practices, you'll also want to look into defining app permissions for your API, so you can then assign privileges to apps to call your API.

azure active directory & postman

I have an Azure web API application which is secured by an azure active directory tenant. Through Postman I am trying to obtain the OAuth2 access token using Postman's OAuth2 Helper. The get access-token requires four bits of info: The tenant auth endpoint, the tenant token endpoint, the client id and the client secret of the associated tenant application. It also seems that the tenant application reply url must include https://www.getpostman.com/oauth2/callback which is where postman is supposed to retrieve the token into the helper.
I can't get this to work. The get access token button reports back an error but it is very hard to decipher what the error is: the debug url reveals nothing really.
Has anyone had any experience attempting to get an AAD Oauth access token with postman's OAuth2 helper? If so, do you have any hints as to where I should look to debug what is going on?
The extension sadly lacks one critical field for Azure AD. AAD must know what resource you want the token for, since a token will not work for all APIs that your app has permissions for. The authorization code is actually retrieved successfully, but the request to the token endpoint fails with an error message about the missing resource identifier. So you can't use it with AAD, neither authorization code or client credential flow works.
Update: The Azure AD v2 endpoint allows you to use the scope parameter instead of resource, which Postman does support!
You can set the resource ID as a parameter to the Auth URL.
Auth URL: https://_______________?resource=https://_________
I am attempting the same authentication flow with the postman app (vs extension). Watching fiddler it appears that the authorization grant is coming back as I see a response from AAD of the form, GET https://www.getpostman.com/oauth2/callback?code=AAABAAAAiL9Kn2Z27UubvWFPbm0gLTo3oWq....
I'm assuming the "code" is the authorization grant because if I attempt to use it as the access token it is unauthorized. Also the fiddler session responds with a 301 Moved Permanently to https://app.getpostman.com/oauth2/callback...
This is my experience with AAD and Postman. You should first validate that you successfully authenticated through AAD and Postman.
Adapted from this post
set up a dedicated 'postman-test' app registration in AD tenant,
with permission to access your target API. Ensure it has the postman callback url previously mentioned.
fill in Postman's OAuth helper form with following details:
Token Name – Any name to save the token.
Auth Url – https://login.microsoftonline.com/{tenant}/oauth2/authorize?resource={testing-appId-uri}
Access Token Url – https://login.microsoftonline.com/{tenant}/oauth2/token
Client ID – Client Id from configure tab of “postman-test” app.
Client Secret – Client secret copied from configure tab of “postman-test” app.
Grant Type – Authorization Code
Note:
tenant It can be either the name of the active directory or TenantId of the admin who created the active directory.
testing-appId-uri is the App ID Uri of the application you are testing. Should include the http:// or https:// and does not need escaping

OAuth and SSO capability

I have been reading about OAuth, and found that
it roughly performs the following
- client sends request token during redirect to server
- Server displays authorization screen to resource owner
- Resource owner provides uid and pw (not passed to client)
- Server sends access token back to client
- clients then users the Access token to gain access to a
resource
Based on my reding it does not appear that OAuth
does not enable SSO or Federation, but on some
Blogs it implies it does perform SSO
Is this correct or incorrect. Can it perform SSO
without the help of other protocols?
Thanks
Yes it supports SSO with this flow.
We have 2 applications A and B.
The user want to access application A
He is redirected to the identity profider (idp)
He logs in with his credentials.
The idp issues an OAUTH token and a cookie
The client now adds the oauth token to the request for app A and is authorized.
When the client wants to access application B he is again redirected to the idp
In this call to the idp the coockie that the idp had returned in the flow with app A is added.
Because of this the idp immediately returns a token for app B, the client does not have to log in again.
The client gan now access app B with the newly created token.
Hope this exmaple flow makes it more clear.

Resources