Amazon Alexa Account Linking doesn't work with Azure AD B2C - alexa-skills-kit

For two days I try to use an Azure AD B2C with Amazon Alexa for account linking without success.
Neither Alexa, neither ad b2c offer a way to debug and I can't see exchange between services.
Is there anybody who have succeeded to do this ?
EDIT: Thanks to Saeed Akhter, I finally succeed in Alexa/B2C configuration.
In AD B2C :
Create a app that represents my web app called by the alexa skills.
Include web api: yes
Authorize implicit: yes
Configure an App ID (https://{tenant}/{myapi})
Save
Publish scope with a descriptive name and a value. The important label is the value and not the name.
Save
Create a second app for Alexa
Include web api: yes
Authorize implicit: yes
Response URL: set the two urls provided by Alexa
Save
Go to Api Access > Add > Select the previous API, select all and save
In Alexa configuration panel :
Authorization URL: take the url found in https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?p={policy}
Client id: The application id of your Alexa app in B2C
Domain List: login.microsoftonline.com
Scope:
openid
https://{your Alexa application id you setted in B2C}/{your custom scope value}
Access token URI: take the url found in https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?p={policy}
Client Secret: The secret generated by B2C for your Alexa app
After that, if you try the account linking from Alexa, everything should work!

Disclaimer: I have not tried this yet and sorry of this is a rehash of things that you've already tried.
I was scanning Amazon's documentation here:
https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system
It seems feasible you could get this working with Azure AD B2C issuing access tokens that are then accepted by your own web resource. Seems like it would be ideal to get the Authorization Code Grant working if possible (instead of implicit).
You will need two app registrations:
1. Alexa App registration
2. Your Web resource registration
Within the Azure AD B2C blade, your Web resource registration will need to define a custom scope. Your Web resource would need to access to that scope, see:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-access-tokens#granting-permissions-to-a-web-api
It sounds like the Alexa App client_id (called Application ID in the Azure AD B2C App Properties blade) needs to be entered in Amazon's developer portal when you setup account linking along with the "scope value" you just defined in the Azure AD B2C blade (please don't use the "scope name" that's just a description of scope)
For the Authorization URL and Token URL you can find them by clicking the "well-known" metadata URL at the top of the blade when you open a policy in the Azure portal. Inside the metadata document you will find "authorization_endpoint" and "token_endpoint".
Is this the path you tried so far? Can you provide me any details on where it fails? Does the login screen appear? do you ever encounter an error?

Related

How to impersonate logged in user to manage other Azure service

I have webapp to make changes in ADF (kinda deployment of objects in ADF). I want to authenticate user against ADF. I am able to detect who is accessing web app. I get Azure AD Id like user1#company.com. I want to validate if the same user has access to ADF and if yes, generate bearer token to make changes in ADF (using rest api) or using SDK.
You can use the way below to get the access token when the user login to the web app, no need to validate if the same user has access to ADF, because if he does not have the access, the token will not be able to call the rest api, he will get the 401 unauthorized error.
1.First, make sure you have configured your web app to use Azure AD login, then navigate to the resource explorer -> find your web app -> add ["resource=https://management.azure.com"] to additionalLoginParams like below -> PUT.
2.Navigate to the Azure Active Directory in the portal -> App registrations -> find the AD App corresponding your web app -> API permissions -> add the permission user_impersonation of Azure Service Management like below.
3.Then when the user login the web app, after he consents the permissions, you can get the token with endpoint https://webappname.azurewebsites.net/.auth/me, and use the token to call the data factory rest api.
4.Make sure the user has an RBAC role e.g. Contributor in your subscription/ADF, then the token will be able to call the rest api successfully.
For example, I test with Pipelines - List By Factory api, it works fine.

Xamarin.Forms app using Azure AD B2C only showing Microsoft login

I’m developing a Xamarin app that uses Azure AD B2C and I’m having some trouble.
Even though I have LinkedIn, Google, Microsoft, Facebook, and Twitter setup as Identity Providers, the only thing I am ever prompted for is my Microsoft account. I don’t see any of the other buttons when my app invokes the login. Works great for Microsoft login, can’t access any of the others.
Here is my call to AcquireTokenAsync:
var result = await AuthenticationClient.AcquireTokenAsync(Constants.Scopes,
GetUserByPolicy(App.AuthenticationClient.Users, Constants.PolicySignUpSignIn),
Evaluator.App.UiParent);
In the Azure AD B2C settings in the portal, I have Web App / Web API set to NO, Native client set to YES. The Custom Redirect URI is “masl{myappid}://auth”.
Under Keys it says “No results”.
Under API access (Preview) it says there are 2 scopes (both checkboxes checked for openid and offline_access).
Under published scopes (Preview) it says Web app / Web API has not been included.
Under Identity providers, I have LinkedIn, Google, Microsoft, Facebook, and Twitter configured.
It turns out that changing to use one of the other overloads of AcquireTokenAsync causes different behavior.
var result = //await AuthenticationClient.AcquireTokenAsync(Constants.Scopes, GetUserByPolicy(App.AuthenticationClient.Users, Constants.PolicySignUpSignIn), Evaluator.App.UiParent);
await App.AuthenticationClient.AcquireTokenAsync(Constants.Scopes, GetUserByPolicy(App.AuthenticationClient.Users, Constants.PolicySignUpSignIn), UIBehavior.SelectAccount, string.Empty, null, Constants.Authority, App.UiParent);
The original call caused the Azure AD service to be called, and the call shown here causes the Azure B2C service to be called instead. I don't see that documented anywhere, and I wish all the overloads had better documentation describing the relevance and distinctions in behavior between them.
Now I see all the providers I had configured showing up as options! However, there's a new problem in that (despite the fact that they appear to be configured correctly) I no longer get an email address back in the result.User.DisplayableId field. Despite this, my original question is answered.
Configure your Policy Identity Providers (IDPs)
Sample Policy

Actions on Google + Account Linking with Firebase

I'm working on a Google home application using an external API. I need the current user to be logged in and linked with the external API (access/refresh token provided by the external API).
My approach:
Setting up a firebase application
The google home app lives within the functions folder.
I would set up a page where the user would first sign in with his Google account using firebase.auth(), then his external API account (using the external API Oauth).
I would then create an entry in the firebase database to store, for each user, an access/refresh token provided by the external API.
This is where I'm a little confused and stuck. I've managed to setup the sign-in page (Google sign-in, then External API Sign-in) and store it the the firebase database (/users/{google_uid}).
Now that it's in the database, how do I set up the authentification in the Google home app?
Thank you!
First, you need to have a project in console.developers.google.com and activate the Google Actions API in your project. Then, you should follow these steps:
Whitelist the following redirect URI in your API:
https://oauth-redirect.googleusercontent.com/r/
In your API.AI project go to Integrations and enable the Actions on
Google Card.
In the setting of the Actions on Google, place your project ID and
select Sign in required for the welcome intent and any other
intent the user needs credentials.
Below, you will find the OAuth2 fields, like clientID, client
secret, authorization URL and token URL. Fulfill it with the OAuth2
information of your API and Authorize the application.
After you authorize, you can Preview the application and it will be available in your Google Home device, and when you invoke for the first time, it will provide a card in your Google Home app to do the linking. If you don`t have a device, there is a Web Simulator where you can test your Action.
For more information access the actions on google documentation.
There are a few issues with how you're thinking about account linking with Actions On Google and Google Home. Google Home doesn't give you direct access to the Google account - instead, it acts like a web browser and the account linking process requires you to issue an OAuth2 token to the Home "browser" for it to use in the future.
If you have control over the external API, and it issues OAuth2 tokens (which it sounds like it does), you can skip the Firebase portion completely. You just need to configure API.AI with the OAuth2 information for this external service - the client ID and secret, the URL for the login page and for the token exchange page, etc. In this case, your webhooks will be called providing the OAUth2 access token that you should pass on to the external API when you're calling it. The details are in the Actions for Google documentation Account Linking documentation.
If you do not have control over this API, you may need to provide a basic implementation of an OAuth2 server that can hand out auth tokens (either ones you create or ones that can be used to get the auth tokens from the external API). Your webhooks will then be called with these OAuth tokens, and you should use the token to find the token to use to access the external API. You have some options to implement this, and these options are discussed at OAuth2 Account Linking Overview in the Actions for Google docs.

Can client and service web applications share the same Azure Active Directory Application?

I have a ASP.NET Web Forms site where users will login using Azure Active Directory. As a client it calls Asp.Net Core Web Api site, that will return some information depending on customer roles.
The approach is similar to https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore sample.
Each application in the sample has it's own Azure Active Directory application. My application has quite a few application roles and maintain them in both applications can be annoying and error-prone. I want client and service to use the same AAD application to avoid maintain the same roles in 2 AAD applications.
I haven't seen such architecture in examples, is any problem with such approach?
I tried to implement it and received a "promising" error, that "scenario is supported".
AADSTS90009: Application is requesting a token for itself. This
scenario is supported only if resource is specified using the GUID
based App Identifier.
Unfortunately I don't understand how to specify resource "using the GUID based App Identifier". In the request I already using GUID
resource=https%3A%2F%2FMyDomain.onmicrosoft.com%2Fe0a25761-XXXX-XXXX-XXXX-2aefc7e3134d
Advice to change some GUID on MS Forums thread https://social.msdn.microsoft.com/Forums/azure/en-US/3de0c14d-808f-47c3-bdd6-c29758045de9/azure-ad-authentication-issue-aadsts90009?forum=WindowsAzureAD#cf3986f5-3422-44d1-bcb7-3a4201f68fa2(I asked for clarifications there) also is not clear.
So my question is: Can I share the same AAD application between client and Service, and, if yes, how to do it?
Based on my test, the normal Azure AD tenant doesn't support to mix the client and server apps well.
Here is my trying for your reference:
1 .Grant the permission to the app itself by modifying the manifest like below:
"requiredResourceAccess": [
{
"resourceAppId": "{AppID}",
"resourceAccess": [
{
"id": "{customOauth2PermissionsId}",
"type": "Scope"
}
]
},
{
"resourceAppId": "00000002-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
"type": "Scope"
}
]
}
],
2 .Then we can acquire the token using OAuth2 code grant flow
https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id={appId}&redirect_uri={redirectURL}&resource={appId}
POST:https://login.microsoftonline.com/common/oauth2/token
However, I was not able to find the custom specific permission when pasred the access_token. If you want the Azure AD normal tenant to support this scenario, you can submit the feedback from here.
I tried to add a new App ID URI for AAD application (identifierURIs[]) that is supported according to https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-manifest .
Manifest allowed to specify multiple identifierURIs, but portals(both new and classic) show only the first of URIs. New portal highlights App ID URI entry box as changed and prompts to save it(effectively removing the second URI).
However I realized that I don't need both AAD applications to have roles. I can have 2 separate AAD applications and keep roles only in one of them. Web Site client will authenticate user, but do not check for roles itself. Instead it will call Web API site that should have AAD application with all application roles declared and assigned to users/user groups. Web API can provide roles/permissions to the client according to client's requests.

Headless authentication with Azure AD (user/pass combination)

I'm following the guide and example provided by Microsoft here and I'm able to get the demo working, with the authentication happening in a console app, then making a request to a Web API with the correct token.
I'm looking to use this but the code in the console app would need to move to a Web App. Essentially: external server tries to access secure Web API, providing Azure AD username/password in the Authentication header of a HTTPS request. I pick up these credentials in the first insecure Web API, and attempt to authenticate the credentials against AD, obtaining the token. From here, I would then call the [Authorize]-protected Web API by making a request with the AD token.
At this point I'm using the same code from the example linked above, simply moving the code in the Console app up into the first insecure Web API controller, but I'm having no luck. I read on CloudIdentity that "You can only use those flows from a native client. A confidential client, such as a web site, cannot use direct user credentials.". Is this true? If so, is there another way to achieve my aim? I need to use the credentials as it may be likely that more services would use the API in the future, so each of these would need their own credentials to use that could be managed within Azure.
EDIT: In reading more around this, should I actually be aiming to use Client authentication, creating an "Application" within the Azure AD, and providing the client ID to each external service looking to call the API, to then authenticate with that, rather than credentials?
Yes, your edit is correct. The Resource Owner Password Credentials grant is meant to authenticate users, not applications. Typical use would be from an application that prompts you for username and password and then retrieves a token from Azure AD.
You can use the Client Credentials grant to get a token from Azure AD from a confidential client to call an API without user context. This flow requires that you register the application in Azure AD and generate a key (which will be used as the client secret). You can then use the ADAL library to ge a token from AAD as shown here.

Resources