Quickbooks Online API: Can API calls be initiated by non-administrators? - quickbooks-online

With QuickBooks Online, administrators can create accounts for non-administrators through the user interface (for example, they can create "time-tracking only" users, which have access to time-tracking tools but nothing else).
Is it possible for these users to authenticate with an app which is owned by the administrator in order to make API calls?
In our testing, when a non-administrator tries to connect via OAuth, they get the following error:
Only administrators can buy apps in the company...
Is it not possible to make API calls on behalf of non-administrators?

You're confusing two topics / talking about two separate things here:
thing 1 - CONNECTING to a third-party app
thing 2 - MAKING API CALLS from a third-party app
Only an administrator can connect to a third-party app.
Once you're connected though, there is no user account involved at all. Your app makes API calls to do whatever, and it doesn't involve an actual user account in any way, shape, or form. Your third-party app can do whatever the heck it wants, regardless of what users you have or who is logged in or anything else.
Remember - the way OAuth works (or should work, if you've implemented it correctly) is that you only connect your app ONCE, and store the OAuth credentials. Your app can then make whatever calls it wants at any time with no user-interaction required what-so-ever using those tokens.
So, to answer your questions:
Is it possible for these users to authenticate with an app which is owned by the administrator in order to make API calls?
If the app is owned by the administrator (e.g. the administrator already connected/signed up for the app) then you are already authenticated, and being authenticated has nothing at all to do with any individual user.
In our testing, when a non-administrator tries to connect via OAuth, they get the following error:
This is the connection process - it is a one-time process to get the OAuth credentials, after which you have can do whatever you want with the API, regardless of what users exist or even if anyone is logged in or anything else.
Is it not possible to make API calls on behalf of non-administrators?
Again, API calls have nothing to do with user accounts. The administrator makes the initial connection to get the OAuth tokens, and then after that the API can do anything without any interaction or relationship with any user what-so-ever.
Once you have those tokens (again, a one-time process) then you can do whatever you want with the API.

Related

Msgraph Api Permissions and public call

What is delegated in Msgraph api. Does it mean we can't use it by creating app on Azure Active Directory.
https://learn.microsoft.com/en-us/graph/api/application-post-calls?view=graph-rest-1.0&tabs=http#permissions
I want to use online meeting and call apis without my customers to register teams or microsoft
Delegated permissions are used to call APIs on behalf of a signed-in user.
If an API only supports them, a user will have to sign in to your application so that you can call the API on their behalf.
Refresh tokens allow you to do this for a long time without requiring the user to interact with the app, but those can and do expire.
Another choice might be to use the ROPC flow, but that requires you to use a username and password to get tokens, and that user cannot have MFA enabled for example (one of many cases where ROPC does not work).
There are two primary mechanisms that an application can use to access the Graph. The one is an "Application" approach, where it needs to be given access rights by an administrator, and can then access certain services / endpoints. There's often an "app secret" that is used in conjunction with the application "Id". This is kind of similar in the past to how we would have created a specific 'service' account + password. ROPC is even more similar, and actually -does- require a username + password, but it's not generally recommended.
The other is "delegated", which means that the application can access certain resources that are specific to that user (like their own mailbox for example). In this case, the user themselves might be required to 'approve' the application's right to access the graph on his/her behalf.
Note that BOTH of these options involve the use of an Azure AD Application, but which permission option you can use depends on the specific operation in the Graph that you're interested in calling. As an example, let's say you wanted to access the list of members in a Teams team. This is explained here, where the "permissions" section indicates that either Application or Delegated permissions can be used to do this. In contrast, here is another operation that can ONLY be done with Delegated permissions, and not by a standalone application without a user granting access.

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.

IdentityServer4 and external check user

Im searching solution about authentication.
I found IdentityServer and Im trying understand how it works.
In my case I need to check user exist in another app.
I have old project created in asp.net web froms and this project have a users collection stored in db.
Now I must create client who will be call to WebApi and in this WebApi I need to authenticate user. I want to do this using IdentityServer4. Can I in IdentityServer call to my old application or db this application and check user by custom method?
In future I want connect another application to IdentityServer and this new application should have users in IdentityServer, so I will be have two places where I will have users for two application. I need to be sure I can check user exist in this two ways.
When request will be form new app IdentityServer should check user in his db and if request is from client who will be call to old app should check this user in external app(db).
Example call:
enter image description here
I dont know I good understand idea of IdentityServer, but generaly I think this is not good solution for my case...For now I understand I can store users in database but only with Asp.Identity in IdentityServer.
What do you think about this case ?
In future I want connect another application to IdentityServer and this new application should have users in IdentityServer, so I will be have two places where I will have users for two application. I need to be sure I can check user exist in this two ways.
When request will be from new app, IdentityServer should check user in his db and if request is from client who will be call to old app, should check this user in external app(db).
The short answer is that IdentityServer4 is just an implementation of the OpenID Connect protocol and the persistence and authentication of users is entirely customisable so you're free to implement that any way you like.
As for where to keep your users - that will depend on your problem domain and business rules but I'd probably try and avoid using multiple DBs if possible and instead migrate existing users from legacy applications to your identity service's own store and take care to only bring over identity and authentication information and not access control/authorization information. i.e. keep the authorization logic in your client applications and APIs.

How to get scope list from service for specifying with client authentication request

I have a UWP app that uses WebAccountManager for AAD authentication. I also have a service, hosted in Azure, used by the UWP app. That service uses the token the UWP app sends to get another on-behalf-of token (I think that's what it's called) to then call other service APIs as the user (e.g. Microsoft Graph and Outlook REST API). In other words, UWP app calls WebAuthenticationCoreManager.RequestTokenAsync to get a token, sends it to my service, my service calls AuthenticationContext.AcquireTokenAsync to get an on-behalf-of token to use when calling the Outlook REST API, for example.
In the AAD registration for my service, the "Required Permissions" list all the services and permissions/API calls it might make on behalf of the user (E.g. "Microsoft Graph"-> "Have full access to user calendars")
When my UWP app creates the WebTokenRequest to pass into the RequestTokenAsync function, it currently passes an empty string as the value for "scope." What should it be passing for the scope parameter? Should it be passing the full and exact list of permissions that the service declares are required? If so, how do I get that permission list to the client? Just hard-code and update the list whenever the service required permissions list changes?
In Azure Active Directory, there are two fundamentally different ways to specify the permissions your app requires when authenticating.
Static Consent
Dynamic Consent
Back in the Azure Active Directory V1 endpoint, you would set "Required Permissions" to other APIs when registering your client application. This is setting up Static Consent. These permissions are fixed, and when you trigger the user to consent to these permissions, the user has to consent to them all at once. Additionally, if at some point your app wants to add new permissions to other APIs, you will need to force the user to go through the full consent experience again, which may even require special logic on your application.
This is why in the V2 endpoint, Microsoft developed Incremental and dynamic consent.
With the v2.0 endpoint, you can specify the permissions your app needs dynamically, at runtime, during regular usage of your app. To do so, you can specify the scopes your app needs at any given point in time by including them in the scope parameter of an authorization request.
Here, you can specify only the permissions your app needs to complete the flows it is trying to accomplish at that time. If you need more access, you can simply add it during your authentication experience, and it will prompt the user only for those new permissions.
Now let's return to your question. If you are using the V2 endpoint, you should be using Dynamic Consent, which means that the settings in "Required Permissions" do not really matter to you. You should be keeping the list of scopes your app requires in your app settings.
Some situations in the V2 endpoint still require Static Consent, like service to service calls with direct application permissions. For those situations you would pass the scope <resource>/.default as noted here. This might also work for delegated tokens, but it is better to just use Dynamic Consent.

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.

Resources