Authentication between a logic app and webhook - azure-active-directory

I have created an Azure function (generic webhook) and I am calling the webhook from a Logic App. This all works successfully however I want to add security so I have enabled authentication on the function app (which contains the webhook function) but now my logic app fails on the step that calls the webhook due to an authorization error. Presumably I need to add some authorization information (client id etc?) into the logic app but I am unsure how to do this?
This is the workflow of the logic app:
And this is where I have enabled authenticationin the function app which contains the webhook:
Any ideas how to get this working?

Related

Service to service requests on App Engine with IAP

I'm using Google App Engine to host a couple of services (a NextJS SSR service and a backend API built on Express). I've setup my dispatch.yaml file to route /api/* requests to my API service and all other requests get routed to the default (NextJS) service.
dispatch:
- url: '*/api/*'
service: api
The problem: I've also turned on Identity-Aware Proxy for App Engine. When I try to make a GET request from my NextJS service to my API (server-side, via getServerSideProps) it triggers the IAP sign-in page again instead of hitting my API. I've tried out a few ideas to resolve this:
Forwarding all cookies in the API request
Setting the X-Requested-With header as mentioned here
Giving IAP-secured Web App User permissions to my App Engine default service account
But nothing seems to work. I've confirmed that turning off IAP for App Engine allows everything to function as expected. Any requests to the API from the frontend also work as expected. Is there a solution I'm missing or a workaround for this?
You need to perform a service to service call. That's no so simple and you have not really example for that. Anyway I tested (in Go) and it worked.
Firstly, based your development on the Cloud Run Service to Service documentation page.
You will have this piece of code in NodeJS sorry, I'm not a NodeJS developer and far least a NexJS developer, you will have to adapt
// Make sure to `npm install --save request-promise` or add the dependency to your package.json
const request = require('request-promise');
const receivingServiceURL = ...
// Set up metadata server request
// See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
const metadataServerTokenURL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
const tokenRequestOptions = {
uri: metadataServerTokenURL + receivingServiceURL,
headers: {
'Metadata-Flavor': 'Google'
}
};
// Fetch the token, then provide the token in the request to the receiving service
request(tokenRequestOptions)
.then((token) => {
return request(receivingServiceURL).auth(null, null, true, token)
})
.then((response) => {
res.status(200).send(response);
})
.catch((error) => {
res.status(400).send(error);
});
This example won't work because you need the correct audience. Here, the variable is receivingServiceURL. It's correct for Cloud Run (and Cloud Functions) but not for App Engine behind IAP. You need to use the Client ID of the OAuth2 credential named IAP-App-Engine-app
Ok, hard to understand what I'm talking about. So, go to the console, API & Services -> Creentials. From there, you have a OAuth2 Client ID section. copy the Client ID column of the line IAP-App-Engine-app, like that
Final point, be sure that your App Engine default service account has the authorization to access to IAP. And add it as IAP-secured Web App User. The service account has this format <PROJECT_ID>#appspot.gserviceaccount.com
Not really clear also. So, go to the IAP page (Security -> Identity Aware Proxy), click on the check box in front of App Engine and go the right side of the page, in the permission panel
In the same time, I can explain how to deactivate IAP on a specific service (as proposed by NoCommandLine). Just a remark: deactivate security when you have trouble with it is never a good idea!!
Technically, you can't deactive IAP on a service. But you can grant allUsers as IAP-secured Web App User on a specific service (instead of clicking on the checkbox of App Engine, click on the checkbox of a specific service). And like that, even with IAP you authorized all users to access to your service. it's an activation without checks in fact.

401 Unauthorized calling my Azure Rest API

I have a Rest API using controllers, etc, hosted in Azure that has been working for some time. I want to secure the various methods. I added the API App (.NET core) to the App Registrations, and also added the javascript client app to App Registrations. I believe I'm initializing everything in startup.cs in the REST Api OK. I added [Authorize] to one of the methods. I used a simple javascript example which calls myMSALObj.loginPopup, and gets back a token which I then add to the Authorization header and make a fetch call. When I call, I see HTTP Error 401.0 - Unauthorized in the log stream for my App Service.
Any ideas how I can troubleshoot this to get more specifics about what is wrong?
Also, a related question: in App Registrations, Api Permissions, how does one correlate the API permission name with the method in the controller?
Add this in front of the method in the controller
[AuthorizeForScopes(Scopes = new[] { "My.Scope" })]

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.

Access AWS API Gateway from Axios

I am attempting to access AWS API Gateway-hosted services from Axios. Using AWS Amplify, I obtain a token using Auth.currentSession() which delivers a CognitoIdToken. Embedded within that object is a jwtToken. I have attempting to call my protected services (authorizer is set to AWS_IAM) using that jwtToken in the HTTP header, trying both the Authorization and x-api-key key, both with no joy. Given a CognitoIdToken/jwtToken, how do you call an AWS API Gateway service with an authorizer of AWS_IAM?
If you're using AWS_IAM authentication then you need to use AWS SigV4 with your access key, secret key, and session key that your cognito user gets as part of their authorization.
If you want to use the cognito JWT as your auth mechanism, you need to change your code to use cognito authentication at the API Gateway level.
I have been using API gateways along with Cognito for authorization for my Vuejs app. You can use following steps to get it configured easily.
Select your API and go to Authorizers option on left panel. Click on Create New Authorizer. Then select cognito and add your Cognito user pool there. Name your Token Source as "Authorization". Keep token validation empty. Click on save.
You can test your new authorizer using JWT token. You can print JWT token on console when you log in using AWS amplify and use that token for testing API authorizer. If you get user information from cognito pool, Your Authorizer is successfully configured.
Next important step is to pass authorized user information from API to Lambda. You need to configure that in Integration request in your resource method. For this, select your method in API gateway and click on Integration Request, then click on Mapping Templates which is last option. Once you click that select 2nd radio button "When there are no templates defined (recommended)". After that in content type click on Add mapping template and give this template name as "application/json". Select this template and at bottom of screen you should see box. In that box you need to write template for getting cognito user details. You can refer following template.
#set($inputRoot = $input.path('$'))
{
"cognitoUsername": "$context.authorizer.claims.email"
}
You can follow this link to get more details about template in AWS
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
Hope this helps.

In IdentityServer4 how does the Google middleware handle the /signin-google callback after successful authentication?

I am using IdentityServer4. I have configured Google authentication middleware as seen here. However, the redirect uri registered with Google is <domain>/signin-google. Additionally, I know that the ExternalLoginCallback endpoint gets called after I have authenticated with Google and after the redirect uri that is registered with Google has been called (/signin-google).
My question is what happens between /signin-google and the call to /ExternalLoginCallback? What method(s) in the Google middleware are triggered once the browser is redirected to /signin-google but before the application/middleware eventually makes it to /ExternalLoginCallback?
If you look at the ASP.NET Core Security Github repo you can find the implementation of the Google middleware. Essentially, if you trace through the code you will see the GoogleHandler inherits from OAuthHandler<T> which inherits from RemoteAuthenticationHandler<T>. In RemoteAuthenticationHandler<T> you will see a method called ShouldHandleRequestAsync (here). This method checks the current URL versus the URL that is on the CallbackPath property on the Options object. This is how the authentication middleware is triggered after the redirect back from the authentication provider - it's handled by the middleware - NOT a controller. Once the middleware is triggered it resumes the authentication process.
All external authentication provider middleware works this way. Once the middleware is triggered a method called called HandleRemoteAuthentication in OAuthHandler is triggered. See here. This triggers the second leg of the OAuth 2.0 authorization code flow process where the one time use code obtained in the first leg of the process is exchanged for an access token. That process happens before the ExternalLoginCallback is triggered. Specifically, once the code has been exchanged for an access token and some user information is obtained from Google a ClaimsPrincipal is created and a temporary cookie is issued. By default the cookie is named idsrv.external. Then, as you can see in the IdentityServer4 Quickstart projects, the ExternalLoginCallback endpoint is triggered, the idsrv.external cookie is deleted and a new authentication cookie is issued for the ClaimsPrincipal.
The Google middleware overrides functionality from the base classes that is specific to Google, but essentially all of the OAuth 2.0/OpenID Connect middleware works this way.

Resources