3

We got the following situation:

External Network

  • 1 some application we don't control

Internal Network:

  • 1 internal api (azure function)
  • Active Directory B2C

I want to secure my internal api according to the official microsoft documentation (first bullet point). But to accomplish this we would need to authenticate the client with active directory.

Since the client calling our api is another application (not a user) we'd need to use the client credentials flow according to OAuth2. The Identity Provider then has to provide me a token containing a custom scope (that the other party can check)

Unfortunatelly after reading a bunch of documentation about how to use the Azure AD I'm not able to retrieve a JWT token that contains a custom scope.

I already tried to register an application in the active directory blade: Application Registration

On its settings page i tried to register permissions (which seems to be the scopes in the world of AD) but it only shows the official microsoft apis. Setting Permissions for a Application

How can i add permissions for an external api?

The token created with the app key also does not contain a "scp" or "scope" claim. How can i get scope claim into the token?

Update 1

I registered an application in the AD B2C Blade for my api (our-api): Azure AD B2C Application for the Api

For the clients I registered applications in the AD Blade (TestClient 1 and TestClient 2): Azure AD Applications for the Client

TestClient 1 requires permission to my "our-api" application: Required Permissions

TestClient 2 doesn't require any permission: Require no permissions

When I try to login to AD with the TestClient 1 I get an access_token as expected. But if I try to login as TestClient 2 I get an access_token as well. Shouldn't this process fail? How can i verify that only TestClient 1 has the permission?

Community
  • 1
  • 1
chrsi
  • 992
  • 9
  • 24
  • Have you tried searching in the Select an API view? It only shows MS apps by default. – juunas Apr 10 '19 at 12:07
  • Also, client credentials grant flow does not get scopes. Those are specific to flows involving users. You need to use application permissions in your case. So the API needs to define app permissions in its manifest, and the client app must require them (and get consent for them). – juunas Apr 10 '19 at 12:08
  • Ok it seems like searching for the API does work. Thank you very much for the tip. I'm still stuck with the whole permissions/consent process. How can the external client require app permissions? – chrsi Apr 10 '19 at 12:31
  • Yeah so the issue is that your API is in your tenant, so they can't require permissions on it. You might have to make your API multi-tenant, have them consent to it and then assign permissions on their client app to call your API. – juunas Apr 10 '19 at 12:36
  • The client is not hosted on azure. I guess this is an issue then? :) – chrsi Apr 10 '19 at 13:00
  • Another choice is that you register the client app in your tenant. Then give its credentials to the other developers. – juunas Apr 10 '19 at 13:02
  • I did that already, and updated my question accordingly (See Update 1) – chrsi Apr 10 '19 at 13:43
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/191605/discussion-between-chrsi-and-juunas). – chrsi Apr 10 '19 at 13:49
  • My understanding is that it will be the responsibility of your api to reject the incoming call as unauthorized based on claims available in the access token. Two ways **1)** simply based on `appid` and `iss` claims.. i.e. your own custom ACL **2)** always look for specific application permission(s)/role(s) being present in token.. I have answered a very similar question here.. https://stackoverflow.com/questions/55407966/is-there-a-way-to-secure-an-azure-function-that-will-only-be-called-from-a-speci/55411680#55411680 – Rohit Saigal Apr 10 '19 at 14:11
  • When I authenticate my user with the following endpoint: https://login.microsoftonline.com//oauth2/v2.0/token I get the tenant-id as the iss-claim. It doesn't really prevent other applications in my tenant from accessing this api. – chrsi Apr 10 '19 at 14:19
  • You should also get `appid` claim which tells the app that is being used.. so you can ensure only certain applications can proceed (that's what I mean by your own custom Access Control List) .. but idea still being that your api needs to implement that logic to check access token claims – Rohit Saigal Apr 10 '19 at 14:25
  • You have to check the token contains a valid scp or roles claim (delegated/app permission). If you are using client credentials, you need to define an app permission and require it. Delegated permissions don't apply without a user – juunas Apr 10 '19 at 14:32
  • The fact that you can get a token to any API without assigned permissions is a less known "feature". You need to check for valid permissions in the token. Note this only applies to APIs. – juunas Apr 10 '19 at 14:33
  • Thank you all for helping. I didn't knew that the application manifest is the only place to configure the app permissions. I get the roles claim now! :) – chrsi Apr 11 '19 at 12:17

1 Answers1

1

How can i verify that only TestClient 1 has the permission?

You could parse your tokens in the jwt.io, you could check the permissions of the token.

v1 token sample enter image description here

When I try to login to AD with the TestClient 1 I get an access_token as expected. But if I try to login as TestClient 2 I get an access_token as well.

First, you could use any app to get access_token for any API that you could find in your app's Requried permission, even though you haven't add it in your app's Requried permission, but you just cannot use this access_token to access the resource of the API, because the token has no permissions. As you mentioned, you created your own API, so the API has no application permissions. And in the client credentials flow, it isn't on behalf of users, so only the application permissions work in this flow, and both of your two test apps' token will have no permission.

SunnySun
  • 1,900
  • 1
  • 6
  • 8
  • And how can i add the application permission to my API? My api permissions only show up as delegated permissions. – chrsi Apr 11 '19 at 07:26
  • This needs the developer to make it. – SunnySun Apr 11 '19 at 07:29
  • Oh, sorry it seems like i asked the wrong question. I couldn't get any app permissions (roles) into my token. But after a few hours of trial and error I figured it out. My api is not a registered app in AD instead of AD B2C, because i need to edit the app manifest which can only be done in the standard AD. There I added the app permission manually and required it from another registered app in AD. – chrsi Apr 11 '19 at 12:13