Headless-Daemon calling AAD secured API
In AAD series of articles, we will see how to call the AAD protected secure API from a headless (or) console application and its authentication flows and scenarios.
In the previous article, we have seen how to register an app in aad. I recommend you to read to get familiar with the app registration concept.
- client_credentials_grant
- username/password
The above grant types allow clients to authenticate silently without any user interaction.
- ClientID: Client App's AplicationID.
- ClientSecret: Client App's "Secret key".
- ResourceID: Consuming endpoint Application Url.
- ClientID: Native Client ApplicationID.
In this article "CogntiveAPIWebDeamonClients" is my Client app registration for headless-daemon which is counter-intuitive. we need to register the client "WebApp Type" to use the "client_credentials_grant" it uses the secret key to authentication.
In this article "NativeCognitiveHeadlessClients" is also my Client app registration for headless-daemon and register as a "Native Type" application.
In this article "CognitiveAPI" is my custom secure API service endpoint and this is where I can get my ResourceID (i.e. App ID URI).
Check here for detailed registration steps
Use the copied values as appropriate, to create the following web.config entries "client_credentials" authenticationClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
Username/Password authentication
UserCredential userCredential = new UserCredential(userName, password);
UserCredential userCredential = new UserCredential();
//Use without parameter if the client runs on same domain in secure environment.
Finally, use the Bearer token from the AuthenticationResult object to access common secure endpoint
Some key points to remember:-
-Ratsub
In the previous article, we have seen how to register an app in aad. I recommend you to read to get familiar with the app registration concept.
How to call the AAD protected secure API from a headless (or) console application
For these types of non-interactive clients, we can use 2 types of authentication flows for different scenarios.- client_credentials_grant
- username/password
The above grant types allow clients to authenticate silently without any user interaction.
oAuth 2.0 client_credentials_grant
Authentication is done based on the valid "Client Secret" used, so this is available only for the "WebApp Type" app registrations. and copy the below information from the respective app registration for later use.- ClientID: Client App's AplicationID.
- ClientSecret: Client App's "Secret key".
- ResourceID: Consuming endpoint Application Url.
Username/Password
Authentication is done based on user credentials, usually, this option is used for "auth_code_grant" where users will have to enter their credential in an AAD signIn popup in the iFrame scenario. But we can also use it for username/password authentication types.- ClientID: Native Client ApplicationID.
where to find this information?
log in to https://portal.azure.comIn this article "CogntiveAPIWebDeamonClients" is my Client app registration for headless-daemon which is counter-intuitive. we need to register the client "WebApp Type" to use the "client_credentials_grant" it uses the secret key to authentication.
In this article "NativeCognitiveHeadlessClients" is also my Client app registration for headless-daemon and register as a "Native Type" application.
In this article "CognitiveAPI" is my custom secure API service endpoint and this is where I can get my ResourceID (i.e. App ID URI).
The code
Create a new Console application and install this NuGet package "Microsoft.IdentityModel.Clients"Use the copied values as appropriate, to create the following web.config entries "client_credentials" authentication
Username/Password authentication
UserCredential userCredential = new UserCredential();
//Use without parameter if the client runs on same domain in secure environment.
Finally, use the Bearer token from the AuthenticationResult object to access common secure endpoint
Some key points to remember:-
- Anyone(or) any authenticated application knows you "Client ID & Secret" can access your API. It's API's responsibility to ensure the current request came from the legitimate client based on ClaimsPrincipal alternatively you can also define custom "Roles" (i.e. Application Permission) & "Scope" (i.e. Delegated Permission) for your API while registering the app in AAD. - How to do this? This will see in the upcoming article.
- Question is as an Azure Admin how to securely share the "Client ID & Secret" to an external ISV or any developer: I could think of 2 options
- If you are creating and hosting it has an Azure App Service as a WebJob, then you create an "Application Setting" and share that key to your the developer.
- Use Azure Key Vault to store and access the key securely, It also provides various security controls/policy/IP range etc.. to expose and access this key.
- If you choose to authenticate using "Native" registration type (Username/Password). then the client is on a trusted sub-system (i.e. Desktop/Server/VM/Laptop) where the client runs in the same domain. But you can still run this client from any domain if you know the username/password and update them in app.config. But still, request legitimate check like "Roles" are in API side only.
Hope I have covered all the nuances of non-interactive AAD authentication. in the next article will see how to use in Windows-Native-App calling secure WebAPI. Catch you all there!
Nice Article thank you for posting this valuable information.
ReplyDelete