简体   繁体   中英

Can OAuth2 tokens be obtained transparently by a service running under an (Azure) AD account?

Apologies if this is actually a naive question. I've searched on the topic but can only find two choices: use a client app registration per client, or a user-password flow that requires a browser window.

Scenario: develop a REST API hosted in IIS, protect it with token authorization via an app registration in Azure AD. Textbook solution says you also create a client app registration in Azure AD, and callers then use the client app's client ID & secret to obtain tokens from login.microsoftonline.com. MSAL code in the API takes care of validation for you. So far so good.

This means creating a client app registration per potential caller though, especially if you want to authorize for different privileges in the API.

My question is: is it possible to have calling applications that run as Windows services say, under domain accounts that are synced to Azure AD, and have those domain accounts added as 'users' in the API app registration? Can the calling application obtain tokens from login.microsoftonline.com transparently, in an NTLM-like way? Or is it impossible without actually storing either a client secret or the domain account's username/password in the client service's app.config?

Yes but the token is an AzureAD token. Not an NTLM or domain account. The thing that makes this behave the way you want is AzureAD sync to AD.

Main library documentation: https://learn.microsoft.com/en-us/do.net/api/microsoft.identity.client?view=azure-do.net

To pull the token for the user account from the OS you need to use a technology called "WAM". Simply add some broker options in your PublicClientApplicationBuilder to enable WAM.

EXAMPLE:

_clientApp = PublicClientApplicationBuilder.Create(_nativeClientAppID)
    // Broker pulls the AAD account from the OS.
    .WithBroker(true)
    .WithWindowsBrokerOptions(new WindowsBrokerOptions()
    {
        // GetAccounts will return Work and School accounts from Windows.
        ListWindowsWorkAndSchoolAccounts = true,

        // Legacy support for 1st party apps only.
        MsaPassthrough = true
    }).Build();

For a service account you may need to log on locally with the service account and authenticate to AzureAD so the OS has the token available for your code to pull from.

NOTE: When AcquireTokenSilent fails you need to be able to AcquireTokenInteractive and a service account has no ability to do so. This means that you need to ensure that the token for the service account never expires. This is a reduction in security to enable your desired workflow.

Details on WAM: https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-acquire-token-wam

Finally, your code should have some way of notifying you if it fails to get the token. This will alert you to the need to enter credentials for the service. I would make an interactive mode, maybe invoked by a -login command line argument, that allows you to provide credentials to the service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM