We are creating an Azure B2C custom Policy and we would like to know if there is any way to call an external API that is protected by an oauth2.
I saw that is only possible to call an API that has Basic or Certificate validated.
Basic: https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-custom-rest-api-netfw-secure-basic
Certificate: https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-custom-rest-api-netfw-secure-cert
Related
I have a front end SPA (single page application) and back end api.
Each event in the SPA (like button click) invokes the respective api endpoint, and displays the result in the SPA.
I want to implement Azure AD based authentication so that only my Azure Tenant users are able to use the SPA/api.
Is the following flow correct approach to implementing such a feature:
User opens the SPA
User clicks on login button which opens Microsoft login popup
User enters Microsoft credentials in the popup, and if credentials are correct then user gets the JWT token
For every subsequent api request, the JWT token is placed in the bearer header
The endpoint validates the JWT token using Azure public key and rejects the request if token is missing or validation fails.
Is this flow correct and what is such a flow called?
There are several implementation steps that needs to be performed before you will have the flow that you have described:
User flow needs to be configured (Azure AD) - e.g. selfsignup allowed?
Backend and frontend applications needs to be registered (Azure AD)
Permissions and scopes needs to be added (Azure AD)
Backend API needs to be configured (e.g. API management) in order to validate the JWT token
I highly recommend to configure one of the Azure sample implementations end2end to get and idea of all the needed tasks: https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-authentication-sample-spa-app
The steps you outlined are correct.
An OAuth 2.0 "flow" outlines the steps to acquire a token from an Identity Provider (IdP). Since you are using a SPA, there are some restrictions on which flows you can use. A SPA can't act as a "Confidential Client" which is required for some flows. (Basically - the Client Secret required for the other flows would be visible in the browser network trace, so it's not "confidential".) The "Implicit Flow" used to be recommended for SPAs but it's less secure, so now the "Authorization code flow (with PKCE)" is recommended. Steps 2 & 3 in the question above are when you are executing the flow to acquire a token.
The authentication flow doesn't really address how you save and send the token to the API (#4 in the question), but the Microsoft Authentication Library (MSAL) helps with that - More information here - https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-overview
In Azure AD, you'll want 2 App Registrations - one for your SPA and one for your API. The API App Registration will need to "Expose an API" which really means to define a scope. Your SPA App Registration will need to Add an "API Permission" to the scope you defined from your API App Registration. (It will show up in My APIs.) This relationship is how #5 in the question is enforced.
Many of the steps for setting up authentication in Azure AD and Azure B2C are similar but Azure AD is designed for authenticating users that are part of your organization. Azure B2C allows you to build a set of users that aren't members of a particular Azure AD organization.
This article states that an issuer has to be login.microsoftonline.com or sts.windows.net when securing a logic app. I have a custom policy where the issuer of the access token is https://{TENANT}.b2clogin.com/{TENANT}/v2.0. How can I secure a logic app using the access tokens that come back from my B2C custom policy?
I’m working on an app that uses Azure AD B2C and .NET Core APIs. We are trying to use a mixture of built in user flows and one custom policy. Built in user flows for sign-in and reset password, and a custom policy for sign-up because we want to follow the invitation sign-up flow demonstrated by this sample app.
https://github.com/azure-ad-b2c/samples/blob/master/policies/invite/README.md
An issue I’m having is on the API authorization side. The JWTs issued from the built-in user flows are encrypted and signed with a different set of keys than the JWTs issued from the custom invitation policy. If I setup the B2C authority for my API project to reference my sign-in flow https://{mytenant}.b2clogin.com/investgradedev.onmicrosoft.com/B2C_1_SI/v2.0 then tokens issued from sign-in are authorized fine but tokens issued from sign-up fail authorization. If I set the B2C authority to reference the custom sign-up policy https://{mytenant}.b2clogin.com/investgradedev.onmicrosoft.com/B2C_1A_signup_invitation
/v2.0, then I have the reverse problem.
Is there a way to have the tokens from both flows encrypted and signed using the same keys? If so, how to I set this up?
Should I force new users back through the sign-in flow to get a token that works?
I’m new to B2C and have been on a steep learning curve so any help provided is greatly appreciated.
No you cannot.
This is possible workaround.
Other option, add multiple Authorities into the API. I did this with AAD and AAD B2C as an example:
https://github.com/azure-ad-b2c/apps/tree/master/apps/spa-hellojs-popup/source-code/.Net-Core-API-RBAC
https://github.com/azure-ad-b2c/apps/blob/master/apps/spa-hellojs-popup/source-code/.Net-Core-API-RBAC/MultiBearerAPI/Startup.cs#L30
We are trying to create a Custom API connector for our API so that it can be used within the Logic App. Our API is OAuth 2.0 protected (OKTA is the authentication provider) and we use client credential grant for generating the token for accessing the API.
The issue is while going into the security tab and selecting OAuth 2.0 and Generic OAuth, there is no option to select the grant type and the fields - Authorization URL and Refresh URL are mandatory. As you know client credential grant will not have authorization URL and Refresh URL. Therefore how can we configure Client Credential Grant?
Also, our API is exposed over Azure API Management and the API in APIM is protected with Subscription Key and the back-end API is protected with OAuth 2.0. Therefore, how can we create a custom API Connector for this API?
I have an API hosted in Azure (Web App). This API can't be accessed directory by every client (IP Restriction), and I am willing to use APIM to protect it.
Users will call the APIM-Gateway and the gateway should responds appropriately.
One big problem is authentication: I am protecting this API (The Backend API and not the APIM-Gateway endpoint) with AAD.
So users should authenticate themselves against AAD and access the resources with no direct access to the backend.
Is it possible to implement such a scenario?
If you're fine with users authenticating against AAD then it's perfectly supported. With that model APIM may be used to just pass-through user requests to backend or you could use validate-jwt policy somewhere in request processing pipeline to validate users' tokens and authorize invoked actions.
APIM's authorization servers feature may be used to document that your APIs require AAD token from certain server. If this is done test console on developer portal will show controls to simplify getting token to make test calls to your APIs.
Normally APIM requires clients to pass subscription keys to authenticate and authorize calls. But if you're relying on AAD that may be not something you want - then you can use Open product to make your calls anonymous to APIM. validate-jwt policy can still be used to require certain token to be present with request.
There are various ways you can ensure that your backend is reachable only via APIM:
Shared secret - set a special header in APIM policy and check it's value on backend.
Client certificate authentication - APIM may be set up to attach client certificate to each request to backend that you will check at backend side to make sure that this is APIM making a call.
VNET - APIM can join your VNET, while backend may be setup to accept calls only within VNET making it possible to be called only through APIM.
I have used below approach in my recent project and used jwt validation to validate oauth2 token in policy
Follow Microsoft document link https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad.
Here is a quick overview of the steps:
Register an application (backend-app) in Azure AD to represent the API.
Register another application (client-app) in Azure AD to represent a client application that needs to call the API.
In Azure AD, grant permissions to allow the client-app to call the backend-app.
Configure the Developer Console to call the API using OAuth 2.0 user authorization. (optional)
Add the validate-jwt policy to validate the OAuth token for every incoming request.