Redirect uri in Azure B2C with query string. Error detail: URL may not contain a query string - azure-active-directory

I'm trying to use Azure B2C OAuth for Alexa account linking with implicit flow.Below is the redirect url from Alexa
https://alexa.amazon.co.jp/spa/skill/account-linking-status.html?vendorId=XXXXXXXXXX
But adding this gives below error in Azure B2C app.
Failed to update xxx-xxxxxxapp application. Error detail: URL may not contain a query string
I tried below link for solving this but its not working
https://blogs.aaddevsup.xyz/2018/04/query-string-is-not-allowed-in-redirect_uri-for-azure-ad/
I also tried auth code grant flow with SPA in B2C. That is also not working with Alexa as it has PKCE - https://github.com/MicrosoftDocs/azure-docs/issues/64073
Anyone succeeded in creating this?

Adding URL parameters isn't allowed in Azure AD B2C.
The document you linked also provides that you use the state parameter. The problem with this is that your Amazon Alexa requires a vendor Id URL parameter.

You can add your own redirection service such that B2C redirects to your service which then redirects to the final application adding any needed query parameters that can be extracted from the B2C claims.

Related

Server side login for Active Directory B2C

I would like to communicate with the Active Directory B2C from my backend to manage users. This seems possible here:
https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0
However, I don't see how to get a login token (or cookies) for a user so the server can send it back to the front-end to have it logged-in. How is it possible to implement this scenario?
I have seen this link but it refer to OAuth.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/add-ropc-policy?tabs=app-reg-ga&pivots=b2c-custom-policy
Thanks!
Azure B2C auth flow cannot generate an access token for Microsoft Graph.
You need to implement AAD auth flow by following Get access without a user or Get access on behalf of a user.

Configure Azure AD B2C as Auth Provider in Salesforce

I am trying to configure Azure AD B2C as auth provider to Salesforce. I followed the instructions in http://salesforce.vidyard.com/watch/kcgTXQytUb6INIs2g3faKg (instead of google used Azure AD B2C).
When I click on the test-only initialization URL I get the following error
My B2C set up is very basic. I just have an email provider and an out-of-the-box sign-in sign-up policy.
Any help will be greatly appreciated.
I'm late to the party but I wanted to post here in case anyone else can use this information. We followed the below steps with an ordinary Custom Policy returning a JWT token. Notice steps 4-5 under Create an Azure AD B2C Application and step 8 under Configure Salesforce Auth. Provider, these will pull back an Access Token from Azure AD B2C.
Create an Azure AD B2C Application
Log into the Azure AD B2C instance you wish to connect to.
Go to Applications. Click + Add.
Add https://www.salesforce.com as a Reply URL. Click Create.
Select the new app you just created. Save the Application ID.
Click Published Scope. Add read as a scope. Click Save.
Save the Full Scope Value.
Click API access. Click + Add. Under Select API, select the name of the application. Under Select Scopes, ensure read and user_impersonation are selected.
Click OK. Select Keys from the left nav. Click + Generate key. Click Save.
Check the value of the generated App key. If it contains “/”, “?”, “&”, or “%” (there may be more invalid characters), delete the generated key and repeat steps 8 and 9 until a valid key is generated. Save the valid key.
Configure Salesforce Auth. Provider
Log into Salesforce. Go to Setup. In the Quick Find box, type Auth. Select Auth. Providers.
Click New.
Under Provider Type, select Open ID Connect.
Add an informative Name. This will be displayed to users as an option when signing in. Salesforce will generate a URL Suffix.
Place the Application ID, from Step 4 of “Create an Azure AD B2C Application”, in Consumer Key. Place the App key, from Step 9 of “Create an Azure AD B2C Application”, in Consumer Secret.
Retrieve the OpenID Connect discovery endpoint of the Azure AD B2C Custom Policy you wish to integrate with. This discovery endpoint can be found at https://{tenant-id}.b2clogin.com/{tenant-id}.onmicrosoft.com/v2.0/.well-known/openid-configuration?p={policy-id}.
Use the authorization_endpoint field in the discovery endpoint as the Authorize Endpoint URL in Salesforce. Use the token_endpoint field in the discovery endpoint as the Token Endpoint URL in Salesforce. Use the issuer field in the discovery endpoint as the Token Issuer in Salesforce.
Place the Full Scope Value, from Step 6 of “Create an Azure AD B2C Application”, in Default Scopes. Add “ read” to the end. (The final value should look something like this: https://{tenant-id}.onmicrosoft.com/{application-name}/read openid)
For Registration Handler, follow Step 11 from these directions: https://help.salesforce.com/articleView?id=sso_provider_openid_connect.htm&type=5
a. Note, in case that link changes. You can create a new Registration Handler using the code in this GitHub repository: https://github.com/salesforceidentity/social-signon-reghandler/blob/master/SocialRegHandler.cls. You may need to add u.CompanyName = 'CompanyName'; in the prepareUserData method.
Pause here, we’ll come back from Token Issuer.
Setup a Dummy User Info Endpoint
Salesforce requires a User Info endpoint. Azure AD B2C does not provide one. You can use the code in this GitHub repository to create a version of a user info endpoint: https://github.com/azure-ad-b2c/samples/tree/master/policies/user-info-endpoint
This code will only return the claims present on the user’s token. We settled on modifying the code to run in an Azure Function.
Whatever your solution, you should end up with a REST endpoint. Place that REST endpoint in the User Info field of the Auth. Provider in Salesforce.
Click Save.
Authorize the Callback URL in Azure AD B2C Application
Click on the Auth Provider configured in the above steps.
Under Salesforce Configuration, save the Single Logout URL.
Expand Communities and save the Callback URL of the Community in which you want to enable SSO.
Return to Azure AD B2C. Navigate to App registrations (Preview). Click All applications.
Select the application created in “Create an Azure AD B2C Application”. Click Authentication.
Click Add URI. Add the Callback URL from Step 3. Update the Logout URL with the Single Logout URL from Step 2. Click Save.
Are you able to test this login endpoint in your terminal using curl, to ensure it is returning the token?
curl -v https://<Azure login endpoint> -d "grant_type=password" -d "username=user#login.demo" -d "password=password"
You may need to add additional parameters to the curl command for Azure (perhaps add a client id & client secret?

How to integrate my activiti app (version 6) with Azure active directory endpoint v2.0 without using ADAL.js or MSAL.js

I have an Activiti app which needs to be integrated with the Azure Active directory for user sign in and authentication. The application is registered on the Azure AD and I have the following information:
tenant ID
CID
key
I am trying to follow the steps in the official documentation here, using the implicit flow.
All the examples I could find for it make use of the msal.js library to authenticate users with Microsoft Azure Active Directory accounts. But i need to achieve this without using any libraries. How do I proceed with this?
How and where in the activiti-UI do i need to put in the code to hit the following URL given in the steps
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&response_type=id_token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&scope=openid&response_mode=fragment&state=12345&nonce=678910
Any examples on this would be of great help!!
Thanks in advance!
For the doc you choose, it does not use a library.
To refer to this doc, your app is required to be registered in the v2 endpoint, like Application Registration Portal or app registration(preview) in Azure Portal. And you also need to enable Allow Implicit Flow for the Web client.
Send the sign-in request in your browser:
https://login.microsoftonline.com/{tenant-name}/oauth2/v2.0/authorize?
client_id=your application id
&response_type=id_token
&redirect_uri=your application redirect urls
&scope=openid
&response_mode=fragment
&state=12345
&nonce=678910
The response like this:
By this, you could get the id_token for the sign-in user. If you want to get the access_token, you need to replace openid in the scope with the resource url with the format(like microsoft graph: https://graph.microsoft.com/User.Read), and replace the id_token with access_token in the response_type.
The access_token response like this:
If you want to parse the token, you could use jwt.io.

B2C as IdP for SalesForce

Completely new to B2C. Tried both of these walkthroughs, but I'm missing something still:
https://github.com/Azure-Samples/active-directory-b2c-advanced-policies/blob/master/Walkthroughs/RP-SAML.md
http://blogs.quovantis.com/saml-based-sso-with-azure-ad-b2c-as-an-idp/
Both of these only describe the policies needed, but I'm pretty sure I need to register an app on B2C still? The problem I have with app registration is that SalesForce gives me a token endpoint URL with a query string:
https://mycompany.cs79.my.salesforce.com/services/oauth2/token?so=00D1h000000Cnli
And B2C won't allow query strings in the reply URL.
Is there any way around this? Salesforce also supports OpenID I think, if that would be better?
::::::::::::UPDATE 6/22::::::::::
SAML:
I found and realized I was missing a critical step on the SalesForce side: adding the authentication provider to my domain's login page. Clicking the new link redirects me to B2C, but I get an immediate error from B2C. Application Insights shows the following exception:
The SAML technical profile 'serviceProviderMetadata' specifies a PartnerEntity URL of 'REMOVED', but fetching the metadata fails with reason 'For security reasons DTD is prohibited in this XML document. To enable DTD processing set the DtdProcessing property on XmlReaderSettings to Parse and pass the settings into XmlReader.Create method.
OpenID:
Using this write-up as a guideline, I've registered the app in B2C and configured the SalesForce side.
Instead of using the Azure AD authorization endpoints, I pulled my B2C tenants endpoints from my meta data URL (login.microsoftonline.com/{tenant}/.well-known/openid-configuration).
This works for my B2C admin account, however, when I try try a test user that isn't a B2C admin I get the following error from the B2C sign-in page:
Sorry, but we’re having trouble signing you in.
AADSTS50020: User account 'REMOVED' from identity provider 'LINK REMOVED' does not exist in tenant 'MTB2CTest' and cannot access the application '5c8b9f4f-cf28-42fe-b629-b87251532970' in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account.
::::::::::::UPDATE 6/23::::::::::
OpenID:
I’ve found that it works 100% only for my B2C admin account if I don’t use a policy, but doesn't work for other accounts. When I use a policy, only accounts that signed up through the policy can authenticate with B2C (which is great) – but the token doesn’t seem to be reaching SalesForce. I've created two PDFs showing the configuration details and the results from each method (policy and nopolicy) here.
Both of these only describe the policies needed, but I'm pretty sure I need to register an app on B2C still?
Not exactly, you no need to register an app at B2C side. All the configuration you do in Policies is enough.
Did you try Salesforce SAML SSO article https://help.salesforce.com/articleView?id=sso_saml.htm&type=5
Check the above article and try to do configurations at Salesforce side and grab the details required by SAML RP
I hope by following both SAML RP and Configure SAML Settings for Single Sign-On articles you can configure B2C as IDP for Salesforce.
I stumbled on this question while trying to implement Azure AD B2C as an IdP for Salesforce. We used Open ID Connect to enable SSO between the two. This involved setting up an Application in Azure AD B2C, enabling the read scope on that application, and configuring the connection in Salesforce using that application, a custom policy returning a JWT token, and a dummy User Info endpoint.
Check out this answer for exact steps on how we set up Open ID Connect: https://stackoverflow.com/a/61639332/13484109

Identity Server 4 (with external Azure AD auth) token is not valid in Graph API

I am switching my application from Azure Active Directory authentication to authentication with Identity Server (using Azure AD as external auth). The authentication and authorization part is implemented and my web API successfully validates token and give me what I'm asking.
Our application also uses external APIs, such as Graph API and SharePoint Online which require Azure AD token. E.g. when I go to https://graph.microsoft.com/v1.0/me from my JS application with token that I get back from Identity Server, Graph API response is
401
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token validation failure.",
"innerError": {
"request-id": "ce7651bb-5dc4-49e9-90ff-02df440ed4ad",
"date": "2017-08-11T08:53:12"
}
}
}
I expected that because Identity Server is giving me his token, and not passing the existing token that is provided by Azure AD. I copied all the claims from Azure AD token into identity server token, but no changes.
What would be the right approach to enable my application to continue using APIs which require Azure AD token?
EDIT:
What I'm hoping for is this.
Click login button on Js (or any other client app)
Redirect to Identity Server login screen
Click on Azure AD external auth
Redirect to Microsoft login page and enter your credentials there
Redirect to Identity server app
a. I started Fiddler and see that "Microsoft" redirect to {IdentityServerAppUrl}/signin-aad (I suppose this is because I configured CallbackPath property on OpenID Connect options). This request carry a cookie idsrv.external. I'm not sure but I think inside is access token from Azure AD. I don't know how to decode this. I tried with base64, but it is not working.
b. When this request is finished redirect is made to {IdentityServerAppUrl}/account/ExternalLoginCallback. In this action method I check with debugger all fields and data in request but I can't find token from AAD. I'm hoping to get token and put it in additional calims.
Identity Server app redirect to JS client app with its own token and additional claim that contains Azure AD token that is valid on graph API and SharePoint.
First I would like to locate Action method or middleware that handle {IdentityServerAppUrl}/signin-aad?
Second, is there any way to get token from Azure AD or any other external provider inside {IdentityServerAppUrl}/account/ExternalLoginCallback Action method?
Be aware that I'm new to this kind of stuff and maybe I'm totally wrong with this thinking.
I manage to do Azure AD authentication without Identity Server, but know we have request to have multiple external providers and I'm hoping to handle all authentication in one app. If one day I get request to have additional external provider I need to add to just in one place.
You need to retrieve an access token from AAD for the Graph API - how that exactly works, check the Microsoft documentation.
Once you have that access token, you can return it as a claim in either the IdentityServer identity or access token (depending if you want to make it available to your front or back-end).
You can also try that first in a simple MVC app to remove the moving partsy - and once you have the AD part working, move your code to the app using the identityserver middleware.
I am also looking for an answer to this question. However, I think it should work a bit differently. IdentityServer gives you a JWT that you can use to authorize to the recources that make up your app. E.g.: yourAPI-1 and yourAPI-2. With the JWT you can pass on the identity. Microsoft Graph is an external resource. Therefore we would need the access token form the Graph API as a claim or external resource, same way as you'd receive an access token for an internal resource.
I would guess that there should be a way of forwarding whatever information you get from the identity provider (Azure AD) to IdentityServer for your client (JS app) to pick up. I am facing the same problem here.
There is another thread about this topic that caught my attention which I will look into. It requires to build your IdentityServer from the source with a few modifications: ASP.NET Identity (with IdentityServer4) get external resource oauth access token
I will let you know what the outcome is and push it to a git repo that you can use if it works:

Resources