Authorize one app service from another (no user in

2020-06-27 13:45发布

I have a Web API app in Azure facing internet (PubWeb), so it's used from anywhere. And I created a Web API (again, in Azure, let's call it InWeb). And I want strong security rules:

  1. InWeb must be used only by the PubWeb. This might involve some network security - that's an easy part (in Azure).
  2. PubWeb must be authorized by Azure AD somehow in order to use InWeb services. Service Principals, certificates, etc comes to mind. But I'm not sure.

So what's the best possible solution for 2?

UPDATE - here's InWeb Core 2.0 Auth setup:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddAzureAdBearer(options => Configuration.Bind("AzureAd", options));

    services.AddMvc(options => { options.InputFormatters.Add(new TextPlainInputFormatter()); });
}

1条回答
该账号已被封号
2楼-- · 2020-06-27 14:41

You will have to register both APIs as applications in Azure AD. This can be done from the Azure Active Directory blade's App registrations.

Now I assume the calls to PubWeb are not authenticated with Azure AD bearer tokens. That means your only option is to use application permissions and the client credentials grant when calling InWeb.

To define an application permission, you must add an "app role" to InWeb's manifest. You can open the manifest by clicking the Manifest button in the InWeb application's blade in Azure AD.

Here is an example app role:

"appRoles": [
{
  "allowedMemberTypes": [
    "Application"
  ],
  "displayName": "Read all things",
  "id": "32028ccd-3212-4f39-3212-beabd6787d81",
  "isEnabled": true,
  "description": "Allow the application to read all things as itself.",
  "value": "Things.Read.All"
}
],

You should generate a new id for it, and set the display name and description to whatever you want. The value is what will be present in the token when PubWeb calls InWeb.

Now you have to go PubWeb's blade, and go to Required permissions.

There you must go to Add -> Select InWeb -> Tick the application permission you just defined.

And then click Grant permissions. Now PubWeb has rights to call InWeb.

You will also need to generate a key/client secret for PubWeb. That is essentially its password. You will also need the client id/application id of PubWeb.

You will also need the App ID URI of InWeb. You can find it from its Properties in its blade in Azure AD. This will be the resource we will acquire a token for from PubWeb.

You will also need your Azure AD's id. You can find it from Properties in the main Azure AD blade.

Now to get the token, you need to use the OAuth2 client credentials grant flow. Easiest way is to use a library like ADAL: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-libraries.

If you want to do it manually, you can find detailed info on the HTTP call here: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service#service-to-service-access-token-request

It looks something like this:

POST /contoso.com/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=625bc9f6-3bf6-4b6d-94ba-e97cf07a22de&client_secret=qkDwDJlDfig2IpeuUZYKH1Wb8q1V0ju6sILxQQqhJ+s=&resource=https%3A%2F%2Fservice.contoso.com%2F

Set the client id to PubWeb's client id, and the client secret to PubWeb's client secret. The resource should be the App ID URI of InWeb.

You should receive an access token in response, which you will need to attach to request's you make to InWeb as a header:

Authorization: Bearer access-token-here

Now of course InWeb will also have to authenticate the token. Here is a .NET example app (there are examples for others too): https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-oauth2-appidentity/blob/master/TodoListService/App_Start/Startup.Auth.cs

That project actually also has a client calling the API with the client credentials flow: https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-oauth2-appidentity/blob/master/TodoListWebApp/Controllers/TodoListController.cs#L95.

Sorry for the lengthy answer, I wanted to put in a bit of detail :)

But feel free to ask if you have questions about some specific parts.

查看更多
登录 后发表回答