Access tokens for Alexa and Google Home - alexa

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

Related

How to use Azure AD access_token and id_token

I have registered two applications in Azure AD, a .Net core web API and a single page react application. I configured these applications to get the id_token for the react client application and an access token for consuming the web API when the user signs in to the client application. I need to send user-specific information to my API when the user signs in (I need to get a unique id from the token to identify the user). Some document says we can't send the id_token to the API since it is issued for the client application. and some says we can't send the user-specific information via access token since it should be used for authorization purpose only.
Is there any other way to solve my problem?
In the context of Open Id connect, is it ok to send user-specific information via access token? I want a unique id from the token and store it in my system to identify the user. if it is ok to use the access token, Which claim is best suited for this purpose (sub or oid)?
You are right that you should not send the id_token to the API. One option is to include the necessary user information as claims inside the access token. Alternatively you could try to ask AzureAD for the user details when the API receives the access token. Azure for example provides the UserInfo endpoint for this.
See this page Microsoft identity platform UserInfo endpoint

Forwarding OAuth 2 credentials from an authenticated request (in GCP specifically)

I have an AppEngine application that is behind an IAP (identity-aware proxy), so it receives requests that are authenticated and include a JWT token. From the AppEngine application I want to make a request to the Google Sheets API. That also requires an authenticated connection, but given that I want that connection to be made under the same user that accessed the application via the IAP, does anyone know how to create a request from inside the AppEngine application that will forward the token to Google Sheets? Cannot find any information on the subject... I am using Java, so any Java pointers would be appreciated, but general/other language help is good too...
I will describe the 2 approach proposed in the comment
The first one, to reuse the IAP proxy token to access Google Sheet is impossible, and dangerous.
Impossible because you receive an identity token from IAP (at least the requester/browser send an identity token to IAP) and you need an access token to request Sheet APIs.
Dangerous because, if you are able to reuse the IAP token to request the Google Sheet, that means the user is authorized to access to the Google Sheet. And I'm sure that you build an app to prevent any direct access/modification to the Google Sheet.
The second one, is to use a technical account (typically a service account) and generate an access token to access the Sheet API.
This second approach is the best one (don't forget to correctly log the user request and the subsequent sheet API calls in your AppEngine app to have the end to end traceability). BUT, and it's for that you ask this question, it's impossible with the App Engine default service account.
In fact, to access to the Sheet API, you need to scope your access token with the Sheet API. Sadly, you can't do this with App Engine. You can do this with Cloud Run, Cloud Functions, Compute Engine (without the default service account, else you need an extra config to achieve this with the Compute Engine default service account). But not with App Engine.
So, you have 2 solutions:
Either you use another hosting platform (Cloud Run for example), but you loose the IAP capacity (for now)
You continue to use App Engine but you need to request an access token to another service account (it's not required to have a service account key file). You can use the Service Account Credential API for this. I wrote an article on this API
Note: later in 2021, App Engine should be able to accept custom service account, and thus the issue should be solved

How to use an Azure AD SSO access token to sign in on another website on a new browser

I have set up an AAD SSO enabled website A that gets an access token once the user logs in. Now, the user has the option to navigate to website B, but on a new browser that doesn't have access to the session of the browser that website A was opened.
Is there a way for website B (.NET MVC Azure hosted Web App) to be setup to accept the access token (for example: through headers) to authenticate the user and establish a newly AAD SSO logged in user on the new browser? (Users can't re-enter their credentials)
In my opinion, access tokens enable clients to securely call protected APIs, so it should be stored in backend. More often we use refresh token and access token at the same time to prevent the access token expiring.
On the other hand, if I have entered the credentials in one browser, then the identity platform knew the request came from me because some information would stored in my cookie of the website, but if I used another browser to visit IDP, it was impossible to let IDP know the request came from me, because I can't share cookie infomation with different browsers.
I find 2 videos on introducing SSO, I think they will help, here is the link.
Hope it will do some help.

Azure AD Account Linking Alexa Skills Kit

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.

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.

Resources