How to authenticate .net core web APIs using Azure AD by using office365 - azure-active-directory

I have .net core 3.1 web api application deployed to Azure App Service. I want to set the authentication for APIs using Azure Active Directory with users logging through their office 365 account.
The architecture is like - I have my office 365 account ready with me. I request for a token to Azure AD. With the JWT, I get from azure AD, I should be able to call all the API endpoints in my web api application deployed in App Service.
Can you please explain what all configuration needs to be done in azure portal and code changes in startup.cs file.

Please refer to Quickstart: Protect an ASP.NET Core web API with Microsoft identity platform.
The Microsoft.AspNetCore.Authentication middleware uses a Startup
class that's executed when the hosting process initializes. In its
ConfigureServices method, the AddMicrosoftIdentityWebApi extension
method provided by Microsoft.Identity.Web is called.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, "AzureAd");
}
You can protect a controller or controller methods using the
[Authorize] attribute.
namespace webapi.Controllers
{
[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Deploying to Azure app service doesn't require more different configurations. Just modify the real API endpoint while calling it.
You can see more details from Scenario: Protected web API.
If you want to call the API from a web app, you could refer to Scenario: A web app that calls web APIs.
Remember that you need to register two Azure AD apps, one is for client app (front) and the other is for API app (backend). In the API app, you need to expose API. Then you need to configure the client app. Add the permission (scope) which is exposed by API app to the client app. These are all mentioned in the links above.
UPDATE:
I assume that you have created the two Azure AD apps on Azure portal and have configured the permissions between them. (if you haven't, please refer to Register the service app (TodoListAPI) and Register the client app (TodoListSPA))
Then you could test your API in Postman like this:
In the second screenshot:
Auth URL: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
Access Token URL: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
Client id and client secret are from the Azure AD app which represents the client app (TodoListSPA).
Scope is the app id uri which is exposed by the Azure AD app which represents the service app (TodoListAPI).

Related

How to use Azure AD to secure an API that needs to be accessed by a 3rd party application?

We are running an API that is configured for and secured by Azure AD. This is working for us with an Angular app where users login interactively.
Now we have a need for a partner firm to use the API in a system to system way (no user login).
What needs to be configured for their application to get an OAuth token for our API from Azure AD?
I've examined the service to service call flow, but I'm wondering if it's best practice to create an application registration in our tenant for an application we don't own/manage. However this seems to be the fastest way to give them a client ID/Secret in order for them to interact with Azure AD.
Thanks in advance!
-Doug
Azure active directory supports the OAuth 2.0 to authorize the
third-party apps too. It doesn’t actually matter where the web APIs
are hosted.You can even see Azure Active Directory
recommendation on third party apps. It actually adds up security
and different type of apps can be integrated .
But you will need to have your web app authenticate to Azure AD, and
provide the token to the web api.so it requires app registration .
Scenario for external web app to call a web api, you can refer to
this:web-app-call-api
Your application can acquire a token to call a web API on behalf of
itself (not on behalf of a user) i.e; you can achieve scenario where
non-interactive app calls a web api
But if you meant app calling a partner api using another api .
The Azure AD V2.0 doesn't support the Partner API(See Restrictions on services and APIs) when you integrated the web API with third-party application using MSAL(Azure AD V2.0 endpoint) .
One way is using the on-behalf-flow. Here third-party application initially acquires the access token to call the web API. This web API acquire the token for Partner Center API and calls it using on-behalf-flow with that token. This solution uses the Azure AD endpoint instead of v2.0( register the app on Azure portal).
Other References:
asp.net web api - Azure Active Directory Verify Access Token in Web
Api outside of Azure - Stack Overflow
Authentication vs. authorization

App services behind Applicaiton Gateway and applicaiton authentication using Azure SSO

I have an application which I am trying to migrate to the App services. The authentication was windows auth before migration so I moved it to Azure SSO.
Background -
The application is registered within Azure to leverage single sign on
and we have a reply URL configured within the application and
redirect URI configured in Azure SSO for URL -
https://abc.customdomain.com
The app is hosted within App services and the Azure endpoint URL of
the app services is https://abc.azurewebsites.net
We have also setup a TXT record created within the custom Domain and
added this to App service to verify the ownership of the DNS.
The custom DNS https://abc.customdomain.com is configured and
pointing to the application gateway.
The application gateway is configured to point to the App service.
Issue
When I try testing the application the SSO works as expected but the moment it tries redirecting to the application after Sign on it breaks because of the incorrect redirect URL as the app services has the URL – https://abc.azurewebsites.net
After setting up a CNAME and pointing it to the App services the hosted site works, but we want to have the traffic flow from the Application gateway.

How to use google authentication for an angular web app and a .net web api hosted on azure

I have an angular web app talking to a c# .net web api back end.
They are both hosted on azure app services.
Azure app services offers a suite of authentication services and I've chosen to use google auth.
I've got my google client id and secret setup in azure google auth and my web app correctly shows and prompts me for my google credentials.
My problem now, is that i need my web api back end to authenticate the web app google token. I couldn't find any articles or tutorials that demonstrates the following:
How to get and send the token to the web api? I've read that azure app service should automatically inject the necessary auth headers but any calls to my api do not include those headers. Should i manually call auth/me and add them to the request header?
How do i get my web api to authenticate the details from the request header with google auth? Do i need a separate client id for the web api or should i re-use the web app client id?
Cheers!
According to your description, I assumed that you are using the built-in Authentication / Authorization provided by Azure App Service.
AFAIK, App Service Authentication (Easy Auth) provides two flows: client-managed and server-managed flow. For the server-managed flow, the server code manages the sign-in process for you, and your backend would directly receive the token from the relevant identity provider (e.g. Google, AAD,etc.), then both generate a authenticationToken for browser-less apps and AppServiceAuthSession cookie for browser apps. Details you could follow Authentication flow.
For your angular web app, you could just use server-managed flow, after user successfully logged, you need to call https://<your-angular-app-name>.azurewebsites.net/.auth/me to retrieve the google access_token, then send the following request against your web api endpoint for retrieving the authenticationToken as follows:
POST https://<your-webapi-app-name>.azurewebsites.net/.auth/login/google
Body {"access_token":"<the-google-access-token>"}
After successfully retrieved the authenticationToken from your Web API endpoint, you could send the following subsequent requests for accessing your APIs:
GET https://<your-webapi-app-name>.azurewebsites.net/api/values
Header x-zumo-auth:"<authenticationToken-generated-by-your-webapi>"
Moreover, you could also use client-managed flow in your angular web app, you may need to directly contact with your identity provider (Google) to retrieve the access_token in your client via Auth0 or google-signin or other third-party libraries. Then you may need to both send request to your angular web app and Web API web app for retrieving the authenticationToken as the above request sample.
Do i need a separate client id for the web api or should i re-use the web app client id?
Per my understanding, you must use the same google application. For AAD authentication, you could configure a AAD app with the access permissions to another AAD app.

Azure AD Apps: Migrating to v2.0

This is my scenario: Client Windows Forms app authenticates with Azure AD and uses the access token to access several web api services. Until now, I was using the endpoint 1 and using the Azure portal to register both apps. It seems like there's a new way now, but I'm a little lost here.
For starters, it seems like both apps (client and server) can be registered in the same app in the new apps portal (https://apps.dev.microsoft.com). I do see a place to add platforms and I have added entries for the native and web api. But where do I go from here? For instance, in the azure portal, I must configure the client app in order for it to call the web api services. How do I that here?
Is there a complete sample for this scenario like the one we have to ADAL (https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-code-samples#native-application-to-web-api)?
Thanks,
Regards,
Luis
Please firstly refer to this document to know what's different about the v2.0 endpoint .When you build applications that integrate with Azure Active Directory, you need to decide whether the v2.0 endpoint and authentication protocols meet your needs. Please see the limitations of azure ad v2.0, such as you can use the v2.0 endpoint to build a Web API that is secured with OAuth 2.0. However, that Web API can receive tokens only from an application that has the same Application ID .
The v2.0 endpoint does not support SAML or WS-Federation; it only supports Open ID Connect and OAuth 2.0 ,To better understand the scope of protocol functionality supported in the v2.0 endpoint, read through OpenID Connect and OAuth 2.0 protocol reference.
You could refer to document how to call a web API from a .NET web app with Azure AD V2.0 (using MSAL to acquire and use access tokens), and here is the code sample on Github . The document includes how to add basic sign-in to a web app or how to properly secure a web API in azure ad v2.0 .

How to enable multitenant authorization (AngularJS <-> Azure AD)?

How can I enable authentication with a multitenant AngularJS single page application calling a multitenant service Web API using Azure AD?
This is the high level flow I am trying to enable:
Multi-tenant AngularJS application [ClientApp] -> Multi-tenant ASP.NET Web API [ServicesApp]
I have a multi-tenant AngularJS application which requires Azure AD login using ADAL for JS (OpenID Connect). That web application is registered as a multi-tenant application ClientApp in a developer Azure AD, which I'll call DevAAD. I consented to use this ClientApp application in another Azure AD, which I'll call Tenant1. Once a user from the Tenant1 directory logs into the web application with their credentials into the login.microsoftonline.com portal, they are able to access the web UI. However, the UI is unable to call Web APIs on behalf of the user using the OAuth 2.0 Implicit Flow. This is the error message I am seeing in the Javascript code:
AADSTS65001: The user or administrator has not consented to use the
application with ID '<ClientApp_ClientID>'. Send an interactive
authorization request for this user and resource.
There is another Azure AD multi-tenant app representing backend Web API services called ServicesApp that is registered in the same DevAAD directory as the ClientApp UI application. The client ID and app ID URI of ServicesApp are the valid audiences for those services. This ServicesApp application has been consented to in the same Tenant1 directory. When invoked from a native client application with permissions to ServicesApp, the services are authorizing users from the Tenant1 directory using the OWIN middleware provided in System.IdentityModel.Tokens.Jwt 4.0.0 and the [System.Web.Http.Authorize] attribute in the controller.
Configuration details:
ClientApp
Azure AD application manifest has availableToOtherTenants set to true and oauth2AllowImplicitFlow set to true. ClientApp has permissions to access ServiceApp Azure AD application.
The AngularJS application has the following configuration:
adalAuthenticationServiceProvider.init(
{
tenant: 'common',
clientId: <ClientApp_ClientID>,
endpoints: { <ServiceEndpoint> : <ServiceApp_ClientID> }
}, $httpProvider);
ServiceApp
ValidateIssuer is set to false in TokenValidationParameters object in WindowsAzureActiveDirectoryBearerAuthenticationOptions configuration object passed to IAppBuilder.UseWindowsAzureActiveDirectoryBearerAuthentication()
"
knownClientApplications" property in "ServiceApp" Azure AD manifest is
set to ["<ClientApp_ClientID>"]
I have not been able to locate any examples of a multi-tenant web application calling multi-tenant Web APIs, specifically a single page application built with AngularJS. How can this be implemented with Azure AD?
You should try generating a Authorization Code URL using the template described here.
You can also copy this and replace the values with your own:
https://login.microsoftonline.com/common/oauth2/authorize?client_id=<appid>&response_type=code&redirect_uri=<replyurl>&resource=<resource>&prompt=admin_consent
Note at the end of the url I added the query string: "prompt=admin_consent".
This is something that only a company administrator can do, and it will consent to your app for the entire tenant, so that no one else needs to consent in the future. Note that you can change this to "prompt=consent" if you want to only consent at an individual user level, or remove it all together if you do not want to force a consent prompt.
Let me know if this helps!

Resources