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.
Related
I am finding it hard to understand how I can differentiate multiple client applications using oAuth 2.0.
Using APIM I mapped my backend webservice to Azure API Gateway Service URL. I have configured Oauth 2.0 with grant type as client credentials because its a service to service integration.
In Oauth registration, I have mapped my client and backend app Id's with secret keys - (OauthSample1.0).
It doesnot have the provision to configure multiple clients for the same backend service.
And, in my API, i can add only one Oauth reference - (OauthSample1.0). Even if i would go ahead and create multiple Oauth 2.0 references for different clients, technically it cannot work with the API configuration.
This means I can have my API validate only one specified client using one oAuth 2.0 reference.
If I want my API to be accessed by different partners / Client applications, my understanding is that I would need to create different Clients in Azure AD. But unfortunately not able to design the solution here.
The official doc for protecting your API using OAuth 2.0 covers the steps required in detail.
To summarize, the steps are
Register an application to represent the API
This app is setup to expose an API
Register separate applications to represent each of your client applications
These apps would also have a secret generated for the client credential flow
These apps would have been granted access to the exposed API
Setup a Validate JWT policy to pre-authorize requests.
Your clients would have to get the token using the client credentials flow before making the requests.
Also, if your clients are services that directly access the APIs, then you could setup app roles that show up as Application Permissions instead of Delegated Persmissions.
I have a cordova application which I am authenticating using azure AD cordova plugin and it all works fine. But now I am integrating services published in another domain and I am unable to authenticate these services using the mobiletoken generated after authentication. Can someone guide me how to secure multiple domain APIs published as Azure web APIs and use token to access the secured APIs.
I have tried to modify the secured settings in azure portal of one of the APIs by including reply URLs for both the APIs
When I include the token in the header of the ajax requests going into 2nd domain endpoints, I just get "unauthorized" error.
It sounds like you're able to get an access token in a Cordova setting and you're having issues accessing multiple web apis after the user has logged in.
The authentication protocol I would suggest you utilize is the on-behalf of flow which is doocumented here : https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
Per the summary :
The OAuth 2.0 On-Behalf-Of flow (OBO) serves the use case where an application invokes a service/web API, which in turn needs to call another service/web API. The idea is to propagate the delegated user identity and permissions through the request chain. For the middle-tier service to make authenticated requests to the downstream service, it needs to secure an access token from the Microsoft identity platform, on behalf of the user.
This is to get a new access token with the right audience to gain access to web api 2.
I'm working with a client to define a security strategy and have got stuck trying to get something working. I'm new to Azure AD so this may actually not be possible.
Consider the following application landscape.
I have 4 "API" applications:
API-A, requires interactive user and role based permissions
API-B, access via service demon, client_credential grant
API-C, must not be authenticated against directly
API-D, access via service demon, client_credential grant
A user / demon authenticated against API-A or API-B should be able to access API-C as well. However the demon authenticated against API-D must not be able to access API-C.
I was expecting to be able to use the "Expose an API" and "API Permissions" of the App Registrations to be able to control to "roles" returned in the JWT, I cannot seem to get it to work or find any decent guide on how this can be achieved.
EDIT: For clarity the API applications are not hosted within Azure, I am just looking to use Azure AD to provide authentication
It may be helpful for you to distinguish between client apps and API apps (or resource servers in OAuth2 lingo). Each of them has to be registered separately. Your list above seems to merge them together, which is a likely source of confusion for you.
The former (client apps) acquire tokens, the latter receive them from the clients with the service request. Authentication is only only involved when client apps acquire tokens. APIs do not authenticate - they use tokens to authorize access to their services. Clients acquire tokens either on behalf of a user - and the user authenticates and consents as part of the process, or on their own behalf (client creds). In AAD an API app may expose/define scopes/permissions which may be included in one or both of these token types. An API may decide not to require any tokens (sounds like your API-C). You Expose (available) Permissions on API apps, you specify (required) API Permissions on client apps. At runtime (if using the AAD V2 endpoint) a client may request fewer scopes than it is is configured with as Required. That applies only if the client is using delegated tokens (user based). (Note that an API app may also be a client app to another API app (common in multi-tier systems).
BTW, where the clients or APIs are deployed is totally immaterial to the above. At most deployment affects the value of the reply url you need to specify for some client apps (not APIs).
I got a HTTP triggered azure function, which is using by one of my web applications. The user of this site would be anybody who signed up to the site. Now I want to implement authentication to the azure function in such a way that only signed up user would able access the azure function through my web site. I could see many built-in authentications like azure functions, OAuth using Azure AD and other identity providers etc. I am looking for to way to authenticate users signed-up through my website, not with identity providers.
One solution I can think of is while signing up a register that user to Azure AD. Then while calling the API pass user credentials to the API and validate against AD. Can somebody please advice this is a good solution? If not please advise the best solution for my use case.
I don't want to use any external auth provider
Just referring to the documentation:
Azure functions HTTP Trigger - Authorization keys
While keys may help obfuscate your HTTP endpoints during development, they are not intended as a way to secure an HTTP trigger in production. To learn more, see Secure an HTTP endpoint in production.
The second link Secure an HTTP endpoint in production gives more insights on how to secure HTTP triggered functions:
To fully secure your function endpoints in production, you should consider implementing one of the following function app-level security options:
Turn on App Service Authentication / Authorization for your function app. The App Service platform lets use Azure Active Directory (AAD) and several third-party identity providers to authenticate clients. You can use this to implement custom authorization rules for your functions, and you can work with user information from your function code. To learn more, see Authentication and authorization in Azure App Service and Working with client identities.
Use Azure API Management (APIM) to authenticate requests. APIM provides a variety of API security options for incoming requests. To learn more, see API Management authentication policies. With APIM in place, you can configure your function app to accept requests only from the IP address of your APIM instance. To learn more, see IP address restrictions.
Deploy your function app to an Azure App Service Environment (ASE). ASE provides a dedicated hosting environment in which to run your functions. ASE lets you configure a single front-end gateway that you can use to authenticate all incoming requests. For more information, see Configuring a Web Application Firewall (WAF) for App Service Environment.
In my opinion you can do this in following ways.
Using function level Authorization key (Not preferred but easy)
If your web app is the only one that will access the function app you may enable authorization directly on the function. Any one who wants to access the function has to pass the key else you get 401 . Since you want your function to be accessed directly by users then you have to create additonal end point in your web site that will call function app on users' behalf and pass the key. You can find more about here
Authorization Key
Using Azure B2C or AD
You are thinking on the right lines. If your website is external consumer accessed then you may consider Azure B2C. You get many out of box functionalities including sign up using social logins and you may not need to save the users separately. The flow remains the same , users get authenticated by Azure AD (or B2C) and token is issued. The token is then passed when calling azure functions.
I have an API Management resource on Azure which uses an API running as a Kubernetes cluster.
I want to have OAuth2.0 authentication for clients/applications which connect to the API management URL. I do not want any user authentication, but only want clients which want to use the URL to send a client ID and client Secret.
How do I do this?
I could not find anything related to this in the documentation.
If you dont want user context to be involved, You must prepare client credential flow from Oauth2.0 which uses client id and client secret.
I am explaining using Azure AD.
1) Create Application in Azure AD and get client id and secret
(https://www.netiq.com/communities/cool-solutions/creating-application-client-id-client-secret-microsoft-azure-new-portal/)
2) Call token end point of Azure AD to get secured token
(https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service)
3) Pass this token to APIM using authorize or from any header
4) Validate JWT and check issuer,audience and application level scopes
(https://learn.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies#ValidateJWT)
No sure what exactly are you asking!
But here are two places where you will find a solution to your question:
How to secure your backend apis: https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad
API Management access restriction policies: https://learn.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies. More specific here check the Validate JWT (https://learn.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies#ValidateJWT)