Azure AD Account Linking Alexa Skills Kit - azure-active-directory

I'm try to link my azure environment to Alexa. I'm using Auth Code Grant with HTTPBasic. After entering Authorization URI, Token URI, Client ID and Client Secret, the Link account page in alexa skill redirects to login.microsoftonline.com. After logging in, I'm redirected to skills.amazon.com which says Unable to link account to your skill. For the alexa endpoint, I'm using an Azure Function App. I'm able to get access tokens when testing on Postman. Has anyone encountered any similar issues? Is this a bug in alexa skills kit or Azure AD?

Here is a blog post that walks through using an Azure Function to back an Alexa Skill and Azure AD. https://blogs.msdn.microsoft.com/premier_developer/2018/01/25/amazon-alexa-skills-authenticated-by-azure-active-directory-and-backed-by-an-azure-function/ It does need to be updated with the following:
You can ignore the sections about the "front end" app registration.
In Alexa account linking section update URLs to use login.microsoftonline.com instead of login.windows.net
ClientId to be the Application Id of the "back end" app registration
The ?resource= has to be set and has to be the same as the audience parameter for the JWT bearer options.
The client secret (key) that is used can not be one that "Never Expires". Use a 1 or 2 year duration.

Related

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.

When should I select openid or email as scope in msal.js executin in browser

I have an entirely client side web page that makes ajax calls to Microsft ASP.NET Core client REST services. Both this UI application and the web service are registered in Azure ActiveDirectory tenants. I have successfully used another ASP.NET Core app registered in the directory to do user authentication and then request a JWT token for the web service and authenticate against that. Nowhere is the ASP.NET Core Authentication code did I have to specify scopes anywhere. If I wanted to call the graph API, I requested a token for https://graph.windows.net and used that.
Looking at this sample, which I made work in my AD, requesting a token for 'user.read' seems to be necessary. However, other samples just use ['openid'] or ['openid', 'email']?
I know that user.read is the AzureAd pernmission to read my entire user profile with the graph api. Does that imply whatever openid and email gives me?
The openid and email scopes are used in Azure AD v2 applications to get access to different info. They are not needed in v1 applications.
Quoting from documentation:
If an app performs sign-in by using OpenID Connect, it must request the openid scope. The openid scope shows on the work account consent page as the "Sign you in" permission, and on the personal Microsoft account consent page as the "View your profile and connect to apps and services using your Microsoft account" permission. With this permission, an app can receive a unique identifier for the user in the form of the sub claim. It also gives the app access to the UserInfo endpoint.
And about the email scope:
The email scope can be used with the openid scope and any others. It gives the app access to the user's primary email address in the form of the email claim.
User.Read is a scope for the Microsoft Graph API. Actually the fully qualified form is https://graph.microsoft.com/User.Read. But MS Graph API is a special case :)

Access tokens for Alexa and Google Home

Where are tokens stored when account linking is completed for Google Home and Alexa?
For example, if I add an Alexa skill for service XYZ and link my XYZ account via the Alexa app, the authorization service will return a token to use for authentication.
I would like to know where this token is stored as it may raise a security issue. Is it stored locally on the device? Or in the Amazon servers?
Amazon stores account linked tokens (access and refresh tokens) in their servers (not on the echo device)
You can not reach this tokens table, but when the user use your skill, Alexa will send current access token of the user to your skill function (for ex: lambda)
In short, if your skill has account linking, then skill developer has to trust Amazon to store tokens securely
The Alexa service stores this token and includes it in requests sent to your skill’s service.
doc: https://developer.amazon.com/docs/custom-skills/link-an-alexa-user-with-a-user-in-your-system.html

Server-side OAuth for user impersonation via GMail API

I am trying to perform server-side OAuth so I can use a specific user account in my domain to send emails (hence using GMail API) via my application.
Mine is a purely server-side app and I cannot perform "user consent" via a UI.
I have created a project in Google App Engine and have obtained service account credentials (P12 key).
My code looks like this -
new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(googleEmailerServiceAccountId)
.setServiceAccountPrivateKeyFromP12File(new File(googleEmailerServiceAccountPrivateKeyLocation)).setServiceAccountScopes(Collections.singleton(GmailScopes.GMAIL_COMPOSE))
.setServiceAccountUser("xxx#xxx.com")
.build()
I have delegated domain wide access to the application (for GMAIL COMPOSE scope) via the admin console as per https://developers.google.com/identity/protocols/OAuth2ServiceAccount.
And I still get an Unauthorised 401 when I try to send emails from my app.
Since there is no explicit documentation for the Gmail API that says it allows domain wide delegation, I am guessing it is not allowed for Gmail.
Is there any way of achieving this programatically?
Any idea would be much appreciated.
Thanks!
As far as I know you cant use a service account with Gmail. Service accounts must be pre authorized.
Authorizing Your App with Gmail
All requests to the Gmail API must be authorized by an authenticated
user. Gmail uses the OAuth 2.0 protocol for authenticating a Google
account and authorizing access to user data. You can also use Google+
Sign-in to provide a "sign-in with Google" authentication method for
your app.
Share a Google drive folder with the Service account. Add the service account email as a user on a google drive folder it has access
Share a Google calendar with the service account, just like any other user.
Service accounts don't work on all Google APIs. To my knowledge you cant give another user access to your Gmail so there will be now to pre authorize the service account.
Recommendation / work around / hack
Create a dummy app using the same client id, authenticate it get the refresh token then use the refresh token in your application.

Use custom account instead of service account in Google API

I am trying to connect to Google Drive from my App Engine code. But it requires Client code. Google App engine generates Client code (P12 key) only for the service account. But I want it for a technical user we have created.
How can I do that?
If the "technical user" you are referring to is a #gmail account, then your only option is to do the OAUTH dance once to obtain a oauth token and refresh token. You have to create a "Client ID for web application" to do this. Once you have the auth and refresh token, you can connect as your "technical user" to Google drive.
If the "technical user" you are referring to is a Google Apps account, then you can authorize the consumer key/secret related to the service account in the Google Apps control panel with the required Drive scopes. You will have to indicate in the API call what user (i.e. the technical user) you want to impersonate when you connect to Google Drive.

Resources