How do I transform a claim to a HMACSHA256 claim in an Azure B2C custom policy? - azure-ad-b2c

I am creating a custom policy to use Azure B2C as an IdP to integrate with a legacy auth service. The legacy service and the new IdP share a secret.
The legacy auth service has a custom authentication flow and requires that an HMACSHA256-based challenge token is sent to it as part of its Auth process using the shared secret as the key.
I am unable to find a way to create/transform a token to an HMACSHA256-based output claim. What are the recommended patterns to address a situation such as mine?
I tried https://learn.microsoft.com/en-us/azure/active-directory-b2c/general-transformations#hash
but the computed hashes do not match.

Azure AD B2C doesn't create or transform HMACSHA254 token.
Also, it is not possible to do transformations on the resulting token. Claim transformation will only apply to claims in the claims bag.

Related

Azure AD B2C: mixing built-in flows with custom policies and sharing encryption keys for JWTs

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

Best way to encrypt data from Azure AD B2C Custom Policy

I need to encrypt a claim through Azure AD B2C Custom Policy.
Is there a sample custom policy that provides a claim encryption transformation?
If there is no direct encryption transformation, is there any Azure REST API that can be call to encrypt a claim from the custom policy?
If you want to encrypt claims, you need to send the claim to the REST API, which can encrypt it and send it back to B2C.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-rest-api-claims-exchange

Azure AD B2c Xamarin Form never signs in silently

I followed the example from this repo https://github.com/Azure-Samples/active-directory-b2c-xamarin-native and got the authentication working. A user can register and authenticate perfectly.
the problem is, after a user is authenticated when this code runs, it can never aquire a silent token.
IEnumerable<IAccount> accounts = await _pca.GetAccountsAsync();
AuthenticationResult authResult = await _pca.AcquireTokenSilent(B2CConstants.Scopes, GetAccountByPolicy(accounts, B2CConstants.AuthoritySignInSignUp))
.WithB2CAuthority(B2CConstants.AuthoritySignInSignUp)
.ExecuteAsync();
var newContext = UpdateUserInfo(authResult);
return newContext;
I have assumed this is about refresh tokens, but I have not found a suitable example on how to accomplish this.
EDIT
here is the policy config
Unfortunately, I have found many times that MSAL is poorly documented. For this reason, many samples and apps that rely on it are not able to provide strong documentation either.
There is a github issue with a similar experience in another xamarin repository that uses the same identity client package:
https://github.com/Azure-Samples/active-directory-xamarin-native-v2/issues/38
Include="Microsoft.Identity.Client" version="4.13.0"
This issue links to the following articles:
https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-net-aad-b2c-considerations#resource-owner-password-credentials-ropc
https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/msal-net-2-released#token-cache-index-keys
Which indicates:
Known issue with Azure AD B2C
MSAL.NET supports a token cache. The token caching key is based on the claims returned by the identity provider (IdP).
Currently, MSAL.NET needs two claims to build a token cache key:
tid (the Azure AD tenant ID)
preferred_username
Both of these claims may be missing in Azure AD B2C scenarios because not all social identity providers (Facebook, Google, and others) return them in the tokens they return to Azure AD B2C.A symptom of such a scenario is that MSAL.NET returns Missing from the token response when you access the preferred_username claim value in tokens issued by Azure AD B2C. MSAL uses the Missing from the token response value for preferred_username to maintain cache cross-compatibility between libraries.
Some workarounds are provided in the Microsoft article, and the GitHub article suggests implementation changes:
Workarounds
Mitigation for missing tenant ID
The suggested workaround is to use caching by policy described earlier.
Alternatively, you can use the tid claim if you're using custom policies in Azure AD B2C. Custom policies can return additional claims to your application by using claims transformation.
Mitigation for "Missing from the token response"
One option is to use the name claim instead of preferred_username. To include the name claim in ID tokens issued by Azure AD B2C, select Display Name when you configure your user flow.
For more information about specifying which claims are returned by your user flows, see Tutorial: Create user flows in Azure AD B2C.
Hopefully, some of these discoveries can put you on the right path.

Can Azure B2C claims exchange be used for Access token?

I got the workaround to work to add claims to the token using a custom REST API, however I realized this is the Id token and not the Access token. I need the custom claims to be the Access token to use for authorization in the service.
I haven't inspected the Access token yet but are these claims also inserted into the Access token?
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-custom-rest-api-netfw
Yes, custom claims come back when requesting access tokens. The only difference in the list of claims is the scp claim. The scp claim is only returned on access tokens.
Unfortunately, the Claims in ID and access tokens documentation doesn't discuss this.
You can quickly verify this via the Run Now feature in the Azure Portal. See this SO answer.
Sample access token w/ a custom claim
I am using custom claims in my Azure Active Directory B2C tenant where I registered two applications (UI and API). The UI passes the access_token to the API and I am able to retrieve the custom claims there. I guess this should be also true for custom claims using a custom REST API.
If not, It must be possible to setup:
... The return claims can be stored in the user's Azure AD account,
evaluated in the next Orchestration Steps, or included in the access
token
If your question is "Can I get the user's access token from the federating IdP such as Azure AD, facebook etc"? The answer currently is no. You can vote for this feature here.
https://feedback.azure.com/forums/169401-azure-active-directory/suggestions/15334347-return-social-idp-s-native-access-tokens-back-to-t

Add claims into token Azure B2C

What are ways to include custom claims (user subscriptions or roles list as example) in a token before issuing it in Azure AD B2C, provided that claims are stored somewhere on own server (not available in B2C)?
Goal to have claims in the token to avoid additional round trip to the storage on every request.
Investigation on the topic brought me to following ways:
Add custom attribute via Graph API, configure to include in JWT. Attribute values should be kept in sync with our datastorage.
Custom Sign-In Policy like in this article https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-rest-api-step-custom but if I got it right, additional Step 6 is a user journey to publicly available API in non restricted way (request not secured by secret, might be used to get user claims by presented UserId)?
IdentityServer4 Federation gateway http://docs.identityserver.io/en/release/topics/federation_gateway.html that will allow to add any claims before issuing.
The first two mechanisms you outlined are the most common and recommended ways to include custom claims in an Azure AD B2C issued token:
Add a custom attribute and include it in the JWT. You can enable the custom attribute via the B2C UI or via the Graph API. You'd need to build your own mechanism to keep the value of this attribute in B2C in sync with your external source via the Graph API.
You can use a custom policy to add a step in your authentication flow to call a Rest API to obtain the claim and include it in the token. This call to the Rest API will be performed by the Azure AD B2C service and NOT the user's browser, so it'll be a service-to-service call (versus a client-to-service call), keeping any secrets you use for authentication with your Rest API safe (such as a Azure function code).

Resources