This question involves Intuit's QBO v3 API.
I have one user ID that has access multiple companies. Affiliates, etc. I'm getting authentication errors when I try to connect to companies other than the first one I queried. Is this because each OAuth connection only gets to talk to one company?
I don't remember specifying a company in the access token acquisition process, so I'm confused about this. I thought this post might be responsive, but it didn't quite address my question.
Each set of OAuth credentials is tied to one specific QuickBooks company.
It's impossible to have a single set of OAuth credentials that's tied to multiple QuickBooks Online companies.
You should be connecting multiple times (once for each company) and storing the OAuth tokens separately for each QuickBooks Online company. When you go through the OAuth connection process, you'll be asked specifically which QuickBooks Online company you want to connect to.
Related
I am currently working on a project that provides a services to enterprises companies. I want companies to be able to set up an account, and link their SSO to it allowing their employees to login. Each company account must have private data, so that other employees from other companies can't access their data. I must therefore be able to identify what account/company the user is from when they log in.
I have been looking into how to set something like this up, I know I should be using OAuth and SSO. But i have been struggling to find any documentation now how SSO integrates with OAuth. Can some one point me to a good guide/documentation on this?
At a high level this is federation, which should work like as follows - and nothing should need to change in your UIs and APIs:
Your UIs and APIs use tokens from your own Authorization Server
Your Authorization Server redirects to Company SSO Systems (Identity Providers)
These Identity Providers can use protocols such and Open Id Connect and SAML
My visual blog post may help you to understand the overall process. Account linking is the tricky bit, where you need to identify the user - most commonly by email - then perhaps match that to data in your own system.
Background
We have created a web portal which our CUSTOMERS can use to host content for their users. Authentication is done through a login page where a CUSTOMER's user enters their email and address and password. Note: Our CUSTOMERS manages these emails. The portal works really well and serves our CUSTOMERS' needs really well. What they need now is the ability to allow our CUSTOMER to enable SSO from their website to our portal. They already know the email address of the user, as it's their customer or supplier. We are looking for the safest and easiest way to do this.
Our tech stack
It's all built on Azure and at the moment we are using ASP.NET MVC and SQL Server. Ideally, we would like to stick to this stack but we are open to any other suggestions. The website is SSL encrypted.
What I was thinking
Add Azure functions to enable a REST API. Give the CUSTOMER a unique API Key which they can use to request a unique "authenitcation_Key" from our API. The "authentication_key" should expire after 60 minutes and is unique for every CUSTOMER/user combination. When the already authenticated CUSTOMER's user clicks on the link/button to go from the CUSTOMER's website to our portal, the website gets a new "authenitcation_key" and adds it to the HTTP Header for us to consume and validate.
What are the major security concerns/risks to this approach? How can it easily be improved?
The one which you thinking to implement will take lots of time and security tests, why not to use industry proven solutions.
I would suggest you to use IdentityServer4, you easily configure this according to your need. I know you are using .NET full framework, but this will not stop you using IdentityServer4 which uses .NET Core.
Check here https://github.com/IdentityServer/IdentityServer4/
If your stack is on Azure, you may just set up an AZURE OpenID Connect server. Your CUSTOMER application can be registered as Openid Connect (or OAuth) client, each request can then send a JWT access_token to your portal, and your portal verify and accept JWT as authentication token.
I am working on a REST API that will be used by a number of clients in different organizations. To be more specific, a client application in an organization will connect to the REST API to exchange information. Multiple users can use this client application. Authentication should be handled by the client application in a way that there is not interaction with the user.
How can this be achieved with Azure Active Directory taking into account that:
I only would like to create one AD user account per organization and not per user in that organization.
A user of the client application should not be aware he is talking to my API, hence he should not authenticate.
The client application should authenticate with the AD account that was provided to the organization.
When an incoming call is received through the REST API, I should be able to identify the calling party.
The examples that are outlined here: https://azure.microsoft.com/nl-nl/documentation/articles/active-directory-code-samples/ never completely cover this scenario:
In the daemon example there is no user interaction, but then I should create a key (secret) for every organization. This seems quite complicated to handle.
In the other scenarios there is always user interaction.
Authenticating with a username and password without user interaction is only supported in .NET: http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/
Any guidance in pointing me to the right direction would be highly appreciated!
I think the question misunderstands the daemon model. In AAD, you create a single application with a single key and then a service principal is created per organization. You only need one key - and you can identify the calling organization by looking at the tid claim in the access token.
According to the Valence Docs,
Valence Learning Framework API calls are all made in isolation, by a known application, and by a known LMS user.
If I want to build an application that has admin access, I'm guessing that I would have to make a "service account" that has admin access, and have my application use the API as that user.
How would I go about obtaining a userId and userKey for users that aren't real people, and only exist for the application to connect to the valence API?
Once you create a Service Account, you need to manually harvest the user tokens using a utility such as the API Test Tool (https://apitesttool.desire2learnvalence.com/) to authenticate with your LMS. You then need to store those keys securely, and configure your LMS to ensure the user tokens are long-lived. Many systems have a token timeout of 30 days, but when a headless integration is in place like the one you're proposing, it's often a good idea to make the timeout infinite. You can contact Desire2Learn Support to verify the timeout value for the user tokens.
There's a similar question that addresses this issue as well: Authenticaton Method for Desire2Learn REST API vs SOAP.
I've just been (re)reading Rob Conery's 2010 blog post OpenID is a Nightmare as part of some research into OpenID/OpenAuth. Ideally, I'm looking to use multiple OAuth providers linked to a single account, to provide resilience against the providers being unavailable - log in with Facebook, link your Twitter and Google accounts, and if next time you visit Facebook login isn't working it doesn't matter, you can use Twitter OR Google to get in and access your stuff - just as, in the real world, you can open a bank account with a passport, and withdraw money later using your driving license if your passport's not available.
One of Rob's primary concerns in his article is that there's no way to consistently identify a user who's using OpenID - somebody might log in with Google one day, buy a product, then come back and log in with Google a few days later and be unable to access the product they bought, because there's no unique identifier that's guaranteed to remain consistent between the two Google authentication calls.
I'm curious as to whether this has been addressed in OAuth 2.0 - either explicitly via the protocol spec, or via some implementation consensus amongst the major providers. Which field - if any - can I rely on not to change for the lifetime of a user's relationship with a particular OAuth provider?
As part of their OAuth2 for login process, Google provide a TokenInfo endpoint that is used to validate and provide information about the access_token that is obtained earlier in the process.
The token information includes userid:
"The value of this field is an immutable identifier for the logged-in user, and may be used when creating and managing user sessions in your application. This identifier is the same regardless of the client_id. This provides the ability to correlate profile information across multiple applications in the same organization."
which sounds like just the ticket (or perhaps token)!
userid is only present if the https://www.googleapis.com/auth/userinfo.profile scope was included in the access token request, so don't forget that.
Similarly, in the Facebook API you have access to the graph API once you've obtained an access token where you can get user data, including ID.
Twitter include the user_id in the access token response as part of their authentication API
If you're using OAuth in a .NET project this might be useful... I discovered today that WebMatrix 2 Beta includes OAuth2 clients for Facebook, Twitter, Windows Live, Google and Yahoo, and can be used from an MVC project. I'm told that you just need the WebMatrix.Security.dll and you're good to go. It's installed into C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies. Although it's in beta and hidden away, it's a good way to get started and might make the the learning curve with the DotNetOpenAuth library a bit less steep.
OAuth 2.0 doesn't solve this - it's not an identity / SSO protocol.
However, OpenID Connect (built on OAuth 2.0) is. You may get lucky and get back the user's email address via OpenID Connect (see here - depending on scopes), or you may get back PPID's which should be unique to a given relying party. Either way - it should be possible.
Alternatively, SAML could be used. It supports many different flavors of user identifiers that would suit.