MSAL and Graph API - access a user's calendar without user interaction? - azure-active-directory

I have an app that runs in a conference room kiosk that displays the conference room's calendar. Right now the app uses the Interactive Credentials Flow to interactively get the room account's token and then fetch the calender. By managing refresh & access tokens we should never have to sign in again and re-grant access.
However - we need to deploy this app to 300 rooms. Sending a technician around to each room and signin with each room's account and grant access is very costly. Also if ever the refresh or access token goes stale or is revoked, we have to send out a tech to the conference room. Some conference rooms are in building where there is no tech in the city.
Is there a way we can do this centrally? To get an access token for a user for granted permissions, then feed this to our application?
We looked at using the "Client Credentials - Application Secrets Flow", but this requires giving the app access to the entire enterprise's calendars. This we cannot do as many of the users require high security.

I find this an interesting question.
here is the documentation on how to achieve this: https://learn.microsoft.com/en-us/graph/auth-limit-mailbox-access
You would use application secret auth, but using this, you can limit which mailboxes the graph calls can access. this would be the most elegant way I believe.

Related

Google Action Disconnect Issue after several weeks in Google Home

One of our customer using the 'Habitat HomeLink' launched year ago, They have been observing after using for a month thermostat devices disconnects in google home and they have to re-link their devices in order to work again.This keeps happening after several weeks.
Please let me know the cause for this issue or any suggestion on this.
Expected the devices stay connected in google home even after many months
Most likely your Access Tokens are expiring after a month, and your service has an issue renewing the Access Token from a Refresh Token.
A refresh token might stop working for one of these reasons:
The user has revoked the app access.
The refresh token has not been used for 6 months.
The user changed passwords and the refresh token contains Gmail scopes.
The user account has exceeded a maximum number of granted (live) refresh tokens.
The user belongs to a Google Cloud Platform organization that has session control policies in effect.
A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
More information in this regard can be found here.

Azure AD OBO Reconsent

I'm currently developing an application which consists of a frontend SPA which makes request to a Node backend. The Node backend makes requests to MS Graph. For this usecase I set up the OBO flow which works fine.
The SPA uses MSAL.js to request a token for middle tier API with /.default scope. The middle tier API knows the client as 'knownclient' in its Manifest. On very first login the application wants the user to consent to the combined scopes from client and middle tier. (If the user never used the app before)
The problem now is the following: By going further in the development process, new scopes are added for MS Graph in the middle tier API. However the client doesn't show the consent prompt to the user for giving his consent to use the new backend scope although using the /.default scope in the client.
The first approach I had was settings prompt='consent' to the MSAL setting in the frontend. This approach works but results in asking the user for consent every time he logs in.
The intended behaviour would be to just ask for consent if the middle tier API changes its scopes.
How do I have to set up my applications to get this result?
As I said in the comments, if you just add new permissions, don't use prompt='consent', because this will cause the administrator consent page to be triggered every time you log in as a user.
When you add a new permission, you only need to grant the administrator's consent, and there is no need to request the user's consent again. So, you only need to grant the administrator consent in the Azure portal. Or, use the url that the administrator consent to: https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id={client-id}.

Why do I need two AAD applications just to add roles into an access token?

As shown by many samples I have two AAD application registrations, one for my javascript-based front end, and one for my JSON-only web APIs.
If I fully trust my client AAD application, why does AAD require me to create a second AAD application for my web APIs?
For example, assuming I add specific roles to my client AAD application, if client signs in with AAD and gets an id token and access token containing my roles, it only needs to send the access token to my APIs. The API only needs to crack the JWT, validate the audience, issuer, tenant, roles permissions, and signature. In this world, no client secret is needed in the web APIs, a second AAD application registration not needed, and still no call to AAD from my APIs. Unfortunately, without two AAD applications, I cannot figure out a way to have AAD include roles into my access token.
If I didn't fully trust the issuer from mucking with claims, I can see why I would need two AAD applications and a client secret. But since I do trust my AAD application and the signature of the JWT, why the extra complexity? Or maybe there is a way to do this that I haven't found?
Thanks!
Responding to Marc here because just not enough characters in the comments field -- The sample you referenced is an excellent sample, specifically the JavaScript one calling the Web API. It is what I am doing right now in fact. However, the problem is that Web API in the sample is open to anybody who has authenticated on the tenant. I need to secure the Web API down to certain individuals in the tenant, and simply checking the client/app id is not sufficient as anybody who can create an AAD app can fake it.
So what I need to do is have roles added to the the access token so I know that my application authenticated the user, and that user has been granted the required roles. For example, here is a Microsoft sample. And even here a Microsoft video walking through the process.
If I don't have two AAD applications w/client secret, the roles claims is never provided in the access token. It is always provided in the id token, but not the access token.
I feel like I am missing something obvious here. If AAD would just put the roles I requested into the JWT when I authenticated against it, and I validated its signature, audience, issuer, and roles, I wouldn't need any of this extra complexity?
Ah, I think I understand where you are going: you would like to control which users can access an API, no matter what client app they are using to access the API with. That's a function of the API - you cannot control that through AAD. In AAD you can control which users can access which applications (UI) using either user access restrictions (enterprise tab) or role-based access. However, access to an API is controlled in AAD at the calling application level via scopes. APIs are never accessed directly by users but only by other apps so controlling access permissions at user level would cause admin havoc. So, you can control what permissions a user has in the app they are using and you can control what permissions that application (client) has in other applications (APIs, resource servers) it is using.
In other words: role is about user access to UI, scope is about one apps' access to another.
App secrets provide added security for getting tokens - they have no bearing on what permissions are included in the token.
Can you provide a link showing that two apps are needed? That should only be the case if the API you want to call is not provided by the web app which served the JS to the browser. None of the 'official' samples require you to register two apps (Graph API, used in some of these samples is a separate API and it is already registered). A problem with tokens passed from the browser is that they were acquired by a public client, not using any secrets apart from user creds. Therefore, they are easier to steal and re-use. Your own back-end app may want to use a secret to get its own token (extension grant) to call yet another API using a token that does not reside in a public client.

Connect a salesforce user to another salesforce user in another org without any user intervention

We would like to connect a salesforce user to another salesforce user in another org without any user intervention from a service.
We have tried SAML Bearer Flow (using Remote Access Application) to connect to salesforce to retreive Access Token for one of our product. We are referring to the follwoing article.
http://help.salesforce.com/help/doc/en/remoteaccess_oauth_SAML_bearer_flow.htm
As referred by the SF article for this flow, it uses a previous user authorization to connect and retreive Token. In case the user (for whom Token is requested) has not already authorized the App, SF takes you to the Authorization page first and app will get the access token once app is authorized. This is working fine too. However it has this painful step of users authorizing the app before we can use this flow for the product. It would be good and simplified if this step can be done once for an org and the article does mentions that either User or Admin can authorize the app. However I am not able to find how an Admin can authorize the remote access application.
Does anyone knows and can guide how can an Admin authorize an App or is thre any other way we can achieve our requirement. Any thoughts will be really appreciated.
OAuth1 and OAuth2 require user intervention by design. Anything you do to defeat this would be circumspect and not best practice. You could make it easy on the user, but you will always have the initial "Authorize this app" message.
If you are trying to make it easy for the user to login to either org, then you may want to consider a hub-and-spoke SSO solution. See this doc.
If you are trying to pass information between two Salesforce instances, then you may want to consider Salesforce2Salesforce, or outbound workflow. However, this is done at system context, not user context.
If you want to maintain user context and security, you should consider the new Salesforce Canvas API. Canvas allows you to call an outbound service, and pass credentials to the service so that it can communicate back. There is no reason the foreign service could not be a Salesforce instance.

Obtaining persistent token for accessing users data under Google domain

I am trying to implement a Google APPs Marketplace application. Some parts of the application are web-based and other parts simply need offline access to users data.
During installation, the Google domain administrator grants access to the data required by the application (e.g Calendar).
For the web-based part of the application, users use OpenID+OAuth, so the application can access the user's data (this works fine).
Questions:
What should be the best practice for the offline part to gain access to users data ?
Do I have to store a persistent access token for EACH user in the domain ?
Can I avoid the need for each user to grant access to their data (after domain administrator has already done this at the domain level) ?
Is there a way to utilize OpenId from a background application ?
Since Sean M in fact answered you to the question no. 4 with his comment, I will handle other three:
You can use 2-legged oAuth. Using 2-legged oAuth, application can access services and data that were granted to it during installation process (for example Read/Write access to Calendar) without any additional approval from user.
In 2-legged oAuth there are no tokens. Instead, the app is provided with oAuth key and secret and uses these to access Google services and read/write data.
More reading:
http://code.google.com/intl/cs/googleapps/marketplace/tutorial_java.html#Integrate-OAuth

Resources