Azure Api Management add path parameter - azure-logic-apps

I am building a multi tenant application. We are not using Azure Active directory.
We are using logic apps as a back-end services. Since each and every API url has a parameter tenant, we wanted to include at the API management level.
https://apm-eso-01.azure-api.net/{tenant}/v1/{siteid}/inventoryItems
Is there any possibility to add path parameter to the host URL at the API Management level rather than including at the logic app as a relative path.
Backend Urls. We have different instnaces/servers for each tenants
Tenant1 :
https://esous-devpd1.host.com/retail/data/esosm/api/v1-beta2/get/1
Tenant2:
https://esospanish-devpd1.host.com/retail/data/esosm/api/v1-beta2/get/1
APIM Urls
https://apm-eso-host-sbx-01.azure-api.net/lse/{tenant}/ esosm/api/v1/get/1
In-order to support the place holder for tenant at the APIM url/endpoints, I should add tenant place holder or path parameter to the backend url as below.
https://esous-devpd1.host.com/retail/data/esosm/{tennant}/api/v1-beta2/get/1
But all my urls should have tenant as a path parameter.
So my question is can we add tenant place holder or path parameter to the APIM end point and just rewrite the backend server url as such to include the tenant parameter rather than adding it to the backend url

This can be achieved by making sure that all operation URL templates in APIM start with /{tenant}/. Then you can add a policy at global or API level to make the transformation:
<rewrite-uri template="#{
var operationPath = context.Operation.UrlTemplate.TrimStart('/').Replace("{*", "{");
var result = operationPath.Substring(operationPath.IndexOf('/'));
return ("/retail/data" + result).Replace("/v1/", "/v1-beta2/");
}" />
This policy will rewrite URI of current request by removing first segment from URI template. So if APIM receives request to /{tenant}/xxx operation it will rewrite it to /xxx.
And then you can add tenant as a query parameter by:
<set-query-parameter name="tenant" exists-action="override">
<value>#(context.Request.MatchedParameters["tenant"])</value>
</set-query-parameter>

Related

Delete document from CosmosDB using Azure Data Factory

My Azure Data Factory has private endpoint connection to CosmosDB and authenticates using System Assigned Managed Identity. The goal is to delete document from CosmosDB using https://learn.microsoft.com/en-us/rest/api/cosmos-db/delete-a-document called from web activity.
I created web activity in Data Factory and put the required headers following those documents
https://learn.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers
https://learn.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources?redirectedfrom=MSDN
DELETE web activity:
I am using Azure Cosmos DB RBAC so my authorization header looks like this:
type=aad&ver=1.0&sig=token-from-oauth
To get a token I was following this post
https://medium.com/analytics-vidhya/azure-data-factory-retrieve-token-from-azure-ad-using-oauth-2-0-9a3ed3f55013
but I don't know where can I get the client_secret. I found my ADF in AAD under enterprise application so I guess client_id is application Id but there is no client secret to be found there.
get token web activity:
First obvious question is where can I find this client_secret?
The second one is why is this token needed at all? Why can't it just use managed identity for authenticating the request?
Where can I find this client_secret?
Go to azure active directory -> Inside mange go to app registration(if you not created a app registration create it ) -> Go to registered app -> Certificate & Secretes.
Why is this token needed at all? why can't it just use managed identity for authenticating the request?
Managed identities are a way to simplify the authentication process for applications running in Azure, but they do not apply to all scenarios when calling external APIs that require authentication. In these cases, you need to obtain an access token from Azure AD using a client secret.
I reproduce same thing in my environment. Follow below approach.
URL:https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/token
Scope : https://cosmos.azure.com/.default
Body: grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>&scope=scope : https://cosmos.azure.com/.default
After execution of web1 activity you will get like this bearer token:
Inside Web2 activity provide valid URL as per below syntax:
https://{databaseaccount}.documents.azure.com/dbs/{db-id}/colls/{coll-id}/docs/{doc-id}
Add dynamic content at header part as shown in the image:
Authorization: Bearer #{activity('Web1').output.access_token}

Azure Active Directory - UI > API - 401 Error

Good Day,
Currently I have a single tenent with a React UI and .NET Core Apis secured by Azure Active Directory without any problems.
We have recently moved to a new Azure Tenent, new Active Directory etc. I have create two new App Registrations, one single App Service for UI and one for API. I have linked the App Service to AAD (UI = UI App Registration, API = API App Registration).
The problem is the API is getting a 401 error and I think see that in the original tenent the Bearer token is in a JWT format but in the new instance it's not, I believe it my be a graph api access key.
New Tenent:
Authorization: Bearer PAQABAAAAAAD--DLA3VO7QrddgJg7WevrQvEQVbZEMD8su-tIp9k2bTFUTort7SZgeDI52P6KRYefHgtmj4YrecgUKZJ2wylGuhvIzIz642n7Sg0VMU1RwKtrzWlaMqK62CaSoJcstxiEf6 *****
Orginal Tenent:
Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiI3OThkN2ZkOC0zODk2LTQxOGMtOTQ0Ny0wNGFlNTQ2OGFkNDIiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83ZDE3NTU3Ni03Y2Y3LTQyMDctOTA5My0wNmNiNmQyZDIwNjAvIiwiaWF0IjoxNjE2NDUyNzExLCJuYmYiOjE2MTY0NTI3MTEsImV4cCI6MTYxNjQ1NjYxMSwiYWNyIjoiMSIsImFpbyI6IkFTUUEyLzhUQUFBQU9mejhPZHp *****
Please someone kindly enought to provide some guidance / input where I am going wrong.
Regards
Paul.
When using Azure AD to obtain an access token, an additional resource parameter is required. Otherwise, the access token is not a JWT.
For example, if your web API's application ID URI is https://contoso.com/api and the scope name is Employees.Read.All, then with oidc-client the client configuration should be :
scope: 'openid profile email Employees.Read.All',
extraQueryParams: {
resource: 'https://contoso.com/api'
}
In App Service auth configuration, you can use additionalLoginParams
"additionalLoginParams": ["response_type=code", "resource=https://contoso.com/api"]
If you did not use a custom application ID URI, it may look like
api://868662dd-3e28-4c7f-b7d5-7ec02ac9c601
Quickstart: Configure an application to expose a web API
Firstly, the scope is incorrect.
You should Expose an API in your API App Registration and then add it as a permission in your UI App Registration. You can refer to this document.
And when you try to call the 'https://login.windows.net/{tenant}/oauth2/authorize endpoint, you need to specify the scope to include api://{app id of the API App Registration}. For example: api://{app id of the API App Registration} openid profile email. Then the access token would be for calling your API.
At last, for CORS issue, please configure the CORS as * in your web app to see if it helps.
Try to follow this step: Configure App Service to return a usable access token
In my experience, this problem occurs, when you try to authorize against version 1 of the endpoint.
Instead of calling
https://login.microsoftonline.com/{tenant}/oauth2/authorize
call
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
You might be required to set something like "metadata URL" in you authorization library to:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/.well-known/openid-configuration
Make sure your builder follows this order...lifted from our API program.cs
These must be in order of
UseRouting -> UseAuthentication -> UseAuthorisation -> MapControllers
> app.UseRouting()
> app.UseAuthentication()
> app.UseAuthorization()
> app.MapControllers()
If app.UseAuthentication and app.UseAuthorization are not in this order in statement position you Will get 401 Unauthorised as at 01/2023 .Net 6 Core.

whitelist domain names on Azure AD with App Registration

The authentication process for O365 requires adding the redirect URL in a whitelist on the app’s dashboard on Azure.
However, this whitelist doesn't work with domain names. It requires to add the entire URL for every page which is not possible if you have a huge number of URLs, plus some of the URLs are dynamically generated by the backend.
Is it possible to whitelist the domain with all its sub-directories/URLs in one go?
No, it is not (unless you want to use wildcards, which you shouldn't).
In general when you need dynamic redirects,
you should store the location you want to redirect to locally in a cookie/session/local storage/session storage.
Then use a single redirect URL, and when you get the redirect there, get that stored "local redirect URL" from where you stored it, and redirect the user there.
I touched upon this on a recent article: https://joonasw.net/view/avoiding-wildcard-reply-urls-with-msal-js

Is it possible to use a single client RedirectUri for multi-tenant application in IdentityServer 4?

I have an IdentityServer 4 setup using SaasKit to support multi-tenant URL paths. This allows me to access the single IS4 instance in a multi-tenant way like so:
https://localhost:5000/tenant/tenant1/.well-known/openid-configuration
The IS4 instance uses a single database for client/scope configuration rather than one per tenant. Only the users database is separated per tenant.
My issue is that a client only ever has one configuration and so has one RedirectUri and PostLogoutRedirectUri, and these values must be tenant specific URL paths otherwise the callback won't be handled in the context of a tenant in the client app.
So, I can specify in my client app's tenant-specific OpenIdConnectOptions new values for CallbackPath, SignedOutCallbackPath and RemoteSignOutPath, e.g. like this:
options.CallbackPath = $"/tenant/{tenant}{options.CallbackPath}";
but obviously this requires the relevant tenant fragment to be included in the client's config RedirectUri property otherwise IS4 will invalidate the redirect uri.
Whilst I could use dynamic clientIds from the client app, I'd prefer not to create a tenant-specific client config in IS4 for each tenant, and deal with the management issues. Likewise, I'd prefer not to add all possible tenant-specific redirect URIs to the single client's config.
Instead, is it possible to implement and register with IS4 some custom components that supports the following functionality, and if so which interfaces should I implement?
A parameterized redirect URI path so the following can be specified:
https://localhost:5000/tenant/{tenant}/signin-oidc
Resolving a parameterized URI path into a real path when redirection is required.
You can implement a custom redirect URI validator.
For that, you need to create a class that implements IRedirectUriValidator and then register it like this:
services
.AddIdentityServer(...)
.AddRedirectUriValidator<MyCustomUriValidator>();
This way you can set the redirect URI for the client in the database using some notation to specify the tenant-dependent part of the URI and then check it at runtime with the custom validator.
Beware of the dangers associated with dynamic redirect URIs.

AAD Token Cache - How to utilize Azure Table Storage as a token store

I have developed a web app that uses Azure Active Directory to authenticate. The application is redirected to AAD, which after authentication, stores a token in a token cache provided by the application. The app then uses Entity framework to retrieve the token, using the location provided by default location, and by default this points to the local database.
My question - is there any way I can change the location of the token store to either a table service or the application cache provided by Azure. I think this will involve configuration on the Active Directory as well as changing the method that retrieves the token.
Are there any open source libraries that will let me do this? Also, are there any publicly available samples that demonstrate this process?
You can use the custom token cache provided by MSAL.In custom token cache, retrive the token and then make an api call to store it anywhere you want.
Here is the api detail
https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/token-cache-serialization
Here is a sample use of the custom token cache
https://github.com/agrabhi/active-directory-b2c-graph-trustframework-policy/blob/master/console-csharp-trustFrameworkPolicy/TokenCacheHelper.cs
Curious, why would you want to store customer tokens though.

Resources