How to add decryption values for jwt and easyauth for azure functions - azure-active-directory

I have an Azure AD app registration that encrypts the JWT tokens it creates and this works well for API management. i decrypt and validate the token in API management with the following policy:
<validate-jwt header-name="Authorization" failed-validation-httpcode="401">
<openid-config url="https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration" />
<decryption-keys>
<key certificate-id="jwts" />
</decryption-keys>
<audiences>
<audience>!redacted!</audience>
</audiences>
<issuers>
<issuer>!redacted!</issuer>
</issuers>
<required-claims>
<claim name="roles" match="any">
<value>Accounts.Read.All</value>
</claim>
</required-claims>
</validate-jwt>
however, when I forward the request to the function app with easyauth enabled I get the following error:
{
"code": 401,
"message": "IDX10609: Decryption failed. No Keys tried: token: '[PII is hidden]'."
}
this makes sense because I haven't specified the decryption key anywhere but I can't seem to find the setting for this value anywhere? does anyone know how to do this?

Please check in case if any of the following are causes
Please check if you have passed App ID in the allowed audiences >:
api://{Azure Function AD App Id }.
Try giving authentication level as anonymous .Also check if function
key is given if the authentication level is not anonymous in your
case. Adding Authentication to Your HTTP Triggered Azure Functions -
DZone Security
Also after the token is received check its issuer endpoint and see if
the accesstokenacceptedversion has the same version.
And check if you need to turn on the system managed identity in apim
and change the inbound access policy to the same in the apim.
References:
Working with Azure Functions and (APIM)
offering (majorguidancesolutions.com)
Securing your Azure Functions App with API Management - Cloud
management at your fingertips (mscloud.be)
using-msal-net-to-call-an-azure-function-app-with-easy-auth-enabled

Related

Multitenant API - Admin consent ERROR https://login.microsoftonline.com/organizations/v2.0/adminconsent AADSTS90009

Using the following endpoint acting as the Admin on the tenantB I want to register a multitenant API App defined in another tenantA:
https://login.microsoftonline.com/{tenantB}/v2.0/adminconsent?
client_id={GUIDAppIDInTenantA}
&redirect_uri=http://localhost:8080/myredirecturi
&scope=api://{GUIDAppIDInTenantA}/.default
I am getting this error:
AADSTS90009 Application is requesting a token for itself. This
scenario is supported only if resource is specified using the
GUID based App Identifier
I am using the GUID based App Identifier from TenantA. I get the login page and after signing in, I am immediately redirected to the redirect_uri with the error above.
The post
OAuth 2.0 and Azure Active Directory - error AADSTS90009 uses a different endpoint and mentions using the GUIDs that I am already using
Replace
&scope=api://{GUIDAppIDInTenantA}/.default
with
&scope={GUIDAppIDInTenantA}/.default
First add the ‘openid profile’ scope like this
https://login.microsoftonline.com/secondTenandID/v2.0/adminconsent?client_id={APP_IP}&redirect_uri={redirect_URI}&scope=openid+profile
This will register the APP (and trust the main Tenant)
Second, submit another request with the actual Multitenant API scope using this format
https://login.microsoftonline.com/secondTenandID/v2.0/adminconsent?client_id={APP_IP}&redirect_uri={redirect_URI}&scope={APP ID}/.default
this way the APP will be registered with the whole scope of permissions from the main tenant in the secondary tenant.
All you need is &scope=.default
https://login.microsoftonline.com/{ConsentingTid}/v2.0/adminconsent?client_id={WebOrSpaAppId}&redirect_uri={RedirectUri}&scope=.default
No need to spell out the app id twice.
If all you are doing is getting consent for you API, you will only need to consent once.
Also, in your MSAL2 client code:
interactionType: InteractionType.Redirect,
authRequest: {
scopes: [
'.default'
]
}

Azure client credentials grant oath not working in hybrid setup for Graph Mail API access

In hybrid setup if client credentials grant type is used to get token and if that token is used to get on-prem user messages (https://graph.microsoft.com/v1.0/users('onpremuser#onpremdomain.com')/messages/) using graph api it fails by providing UnknownError.
When debugged on IIS logs error shown was "This token profile 'V1S2SAppOnly' is not applicable for the current protocol." error_category="invalid_token".
However if authorization code grant or resource owner password credential (ROPC) grant if used to obtain token , we were able to get messages of on prem user using graph API.
Have attached screenshot of token for both. How to make client credentials grant work for on-prem user messages access using graph API (in hybrid setup) ?
Update
Update i went and edited web.config of rest in Exchange server to have V1S2SAppOnly in profiles. After that previous error is gone and new error is seen.
Bearer+client_id="00000002-0000-0ff1-ce00-000000000000",+trusted_issuers="00000001-0000-0000-c000-000000000000#ea6064aa-d6fc-48d3-abb8-1728e1f39e0b",+token_types="app_asserted_user_v1+service_asserted_app_v1",+error="invalid_token" 2000008;reason="The+token+should+have+valid+permissions+or+linked+account+associated+with+partner+application+'00000003-0000-0000-c000-000000000000'.";error_category="invalid_grant"
I think the problem is with the aud claim, i.e. the audience for token.
For the first token that you have shared
aud value is 00000002-0000-0000-c000-000000000000. This is the resource Id for Azure AD Graph API and not Microsoft Graph API. For Microsoft Graph API, you should be using https://graph.microsoft.com or Id 00000003-0000-0000-c000-000000000000
this token is probably the one where you used client credentials grant, as there isn't any user claim
For the second token that you have shared
aud value is https://graph.microsoft.com which is correct
this token is acquired in context of a user name anoop so I guess this is the one which is working for you.
What you want is:
Application with Client credentials => Graph API => Local Exchange.
This scenario isn't supported out-of-the-box, but you can however tell your local exchange server to accept those tokens. See this answer https://stackoverflow.com/a/56131954/639153
In a nutshell, you need to change the authentication config of your front-end exchange servers to accept client credentials from the graph api. By default only delegated credentials are supported, and these settings are not documented on the exchange side.
Warning, we tested these settings, and it's working but not supported by Microsoft
This is the blog where I've found the answer to your question. https://blog.thenetw.org/2019/05/13/using-client_credentials-with-microsoft-graph-in-hybrid-exchange-setup/

Swaggerbuckle with AAD --Error AADSTS500013: Resource identifier is not provided

I'm trying to use AzureAD to get a token in swagger and test my .netCore2.1 API with it.(using Swashbuckle.AspNetCore 4.0.1)
To do this I completed the following steps
1. Created a Web API project(asp.net Core2.1)
2. Register an Azure AD (AAD) app for the Web API
3. Updated the Web API project to use Azure AD authentication
4. Register an AAD app for the Swagger web site https://localhost:5001/swagger
5. Granted permissions for the Swagger AAD app to access the Web API AAD app
6. Generated a Client Secret for the Swagger AAD app
7. Enabled OAuth2 implicit flow on the Swagger AAD app
8. Added Swagger to the Web API project
When I authenticate, I am getting the following error.
Error AADSTS500013: Resource identifier is not provided .
When I click authorize
I am getting error AADSTS500013: Resource identifier is not provided.
My WebAPI project's startup.cs file goes here
Please help me understand which resource Identifier I am missing here or how to resolve this error.
Or any pointers on how to use Swaggerbuckle with ASP.NET Core webAPI, especially with AAD authenticated WebAPI ?
UPDATES
I copied my webAPI's APPID URI from azure portal. ie Dashboard>>Microsoft - App registrations>>MY_API_APP>>Settings>>Properties>>App ID URI
But I am still getting the same error when I try to authenticate
Error AADSTS500013: Resource identifier is not provided
Usually resource identifier which uniquely identifies your application. You can easily found your resource Identifier Like below:
When logged into the Azure portal, Azure Active Directory > App Registrations > [App Name] > Settings> Properties, then it's the App ID URI
See the screen shot:
In the orignal OAuth 2.0 specification, there is no resource parameter in the authorization request. It use scope parameter. The authorization and token endpoints allow the client to specify the scope of the access request using the "scope" request parameter.
As document explains, when Azure AD implement the OAuth 2.0(1.0 endpoint), the resource is used to specify the access_token you request for which resource. And the Azure AD will issue the token which the scp based on the permission you config on the portal for the resource.
And in the v2.0 endpoint, the Azure AD also use the scope to support the dynamic permission request. More detail you can have a look here.
Usual Reason for Error
Make sure you have configured below steps accordingly.
Like below:
Application Manifest
Reply URI
Request Endpoint
For V1.0 refer this URI https://login.microsoft.com//oauth2/authorize
For V2.0 refer this URI https://login.microsoft.com//oauth2/v2.0/authorize
Application Consent
Need to confirm your application required resource access permission you could refer here
I believe this step can lead you to sort out your problem.
With Azure AD V1.0 app you need set resource to identify which api you want to access during the authentication&access token requests :
Code flow :
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code
Implicit flow :
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-implicit-grant-flow
In Swashbuckle.AspNetCore 4.0.1 , you need to config the resource as parameter if you want to get access token for accessing your web api :
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "MySite API V1");
options.OAuthClientId("19c73866-562f-482a-bafb-89d9fe9b0aaa");
options.OAuthAppName("Swagger Api Calls");
// add resource
options.OAuthAdditionalQueryStringParams(new Dictionary<string, string>() { { "resource", "f479db30-9b62-431b-98c2-bcaae52203cf" } });
});
For us Nan Yu's response got us one step closer.
We added the resource in the AdditionalQuerystringParams like so:
options.OAuthAdditionalQueryStringParams(new Dictionary<string, string>() { { "resource", "{ResourceIDHere}" } });
We are now able to get passed the Auth step in Swagger, but trying routes out doesn't seem to pass the token to the api called and so we get a 401 Error.
change { "scope", API_AppID_URI} to { "resource", API_AppID_URI}

What happens during a AcquireTokenAsync call using the client certificate?

In Azure AD, when we make a call such as AuthenticationContext.AcquireTokenAsync(resource, new ClientAssertionCertificate(_clientId, _cert)) it is not clear what exactly happens.
What part of the certificate gets exchanged if any?
Is there a challenge/response taking place?
Is the private key needed on the client as a part of this?
There are two ways you could go about finding the answer to you questions. One would be to look at the Microsoft Active Directory Authentication Library (ADAL) for .NET source code on GitHub, since this is open-source. The other (which we'll do here) is to looking at the network request that AcquireTokenAsync(String, ClientAssertion) generates, and work backwards from there.
Using Fiddler (or any other traffic analyzer), we can see something like the following (formatted for readability):
POST https://login.microsoftonline.com/{tenant-id}/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&resource=https%3A%2F%2Fgraph.windows.net
&client_id={app-id}
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ
Breaking it down:
grant_type=client_credentials tells us this is a token request using the OAuth 2.0 Client Credentials Grant flow.
resource=https%3A%2F%2Fgraph.windows.net gives the URI of the resource the client is requesting an access token for. In this case, it's for the Azure AD Graph API.
client_id={app-id} is the client identifier. In Azure AD, this is the app ID of the application that was registered.
The presence of client_assertion_type and client_assertion are indicative that the client is using an assertion to authenticate:
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer says that client assertion being used is a signed JSON Web Token (JWT).
client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ is the aforementioned signed JWT token. The authorization server (e.g. Azure AD) will validate the contents, and check that the token was indeed signed by the certificate authorized for the client in question.
So, what ADAL does is:
Construct a token with a set of claims about the client (your app)
Use your certificate's private key to generate a cryptographic signature of those claims
Bundle that up into a signed JWT
Make an appropriately formed token request to the authority
During AcquireTokenAsync, only the certificate's thumbprint is provided (it's included in the JWT header to help the authorization server look up the corresponding public key). The JWT's signature is what proves that the client is in possession of the private key. However, before AcquireTokenAsync(String, ClientAssertion) can be used successfully, the client owner (i.e. you) needs to have provided Azure AD with the certificate's public key.
There is no challenge/response taking place here. The token is obtained in a single request, initiated by the client.
For a lot more detail, you can review the standards that this all implements:
RFC 6749: The OAuth 2.0 Authorization Framework
RFC 7521: Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
RFC 7519: JSON Web Token (JWT)
(Note that ADAL has a cache. Everything I described above will take place only if ADAL does not find a valid access token in the token cache. You can use AuthenticationContext.TokenCache.Clear() to clear the cache for experimentation.)

Missing Application Claims when completed SignUp policy on Azure B2C

I am implementing the Azure B2C preview in our mobile app but I am having trouble retrieving the application claims once the Signup policy has completed and the redirect_uri is called. I have specified the claims I need returned through the "Application claims" section of the policy blade and similarly through the other two policies (Sign-in and Profile) but I never receive a JWT along with the access code on the callback to the redirect_uri.
I have also tried HTTP and HTTPS in the redirect_uri and using the different response_mode settings but all i get is the code returned.
Am i missing something, or does the signup policy not support returning other claims at this point. I was planning on using them to send a welcome email to the new user.
I think i may have just realised - i need to make a call to the token endpoint to swap my code for the id_token and then i can get the claims.

Resources