Power Query Windows authentication with Odata feed - odata

I am currently trying to find a way for a customer to connect with Power Query (plugin for Excel) to access their published Odata-feed (which is hosted by Microsoft NAV 2013 R2).
For security reasons the NAV server is set to only accept Windows as an credential type. This means that the current user credentials on the client is passed on to the webservice.
The problem: The users of the system is often off site and working on another domain with a VPN connection to the NAV-environment. With that said Power Query does not pass the "correct" AD-information to the published Odata-feed which means that the user is not authorized.
I am looking for a way to change which AD-credentials that are sent thru Power Query and then to the Odata webservice.
The users have no problem typing in the webservice adress in a web browser and type in the Windows credentials when prompted and access the feed. But in Power Query there is no option for typing in custom Windows Credentials when refreshing the data.
I've tried with WebAPIKey and Basic authentication. But since the NAV-server/Webservice is set to only accept Windows authentication I'm in the dark..
Any thoughts?

I got this answer from Curt Hagenlocher (Moderator on Technet)
I'm afraid this isn't something we currently support, though we have
considered implementing it. We do loosely track feature requests and
use them to prioritize future work.
(https://social.technet.microsoft.com/Forums/en-US/03c529ba-5f20-4bc1-84de-35cc91e7c1a6/power-query-custom-windows-credentials-authentication-with-odata-feeds?forum=powerquery)

Related

Why is the company file name supplied by the web service?

I understand that to access a company that is not currently open in QuickBooks, the web service needs to supply QuickBooks Web Connector with the file location as a return value to an authenticate() call.
This seems backwards to me. Why would the web service be in charge of telling the Web Connector where the relevant company file is? Wouldn't it make more sense for it to be managed by the Web Connector?
Here's the relevant explanation I've found within the QuickBooks Web Connector
Programmer’s Guide:
IF your web service wants to try a different company, supply the company pathname in the returned string. (You can supply an empty string if you want to use whatever company file happens to be open.) The web connector will respond by attempting to connect to QuickBooks again using that supplied string.
Why Would a Web Service Try a Different Company?
Why would a web service perform the second of these actions instead of simply just stopping altogether? In practice this approach is used when the web service remembers the company file path from session to session (a recommended practice) and wants to have a fall-back to use whatever company file is currently open in QuickBooks (by responding to the connectionError call with an empty string).
This is not as haphazard as it might seem. When a web service is added to the web connector, the web connector stores a unique FileID as a private data extension in the specified company. As a result, the web service can always verify that it is talking to the expected company file simply by checking the CompanyRet returned to your web service in the web connector’s first sendRequestXML call in the data exchange sequence. (Check the data extension list for the expected FileID.)
This seems like a poor end-user experience; if they move their company file (assuming they want the Web Connector operate without QuickBooks open), the web service will fail until that path is updated on the server side. It seems totally plausible that an end-user could do this without knowing it would break things.
Why is it structured this way? And more importantly: is there a way around this?
Why is it structured this way?
Because this is how Intuit built it.
is there a way around this?
No.

Connect to already open Quickbooks instance via QBXML

I'm trying to help a client who has a web application (ASP/C#) that integrates with Quickbooks via the QBXML SDK.
I want to open up a connection to an already active QuickBooks instance in a user session.
The relevant code in question:
if (rp == null)
rp = new RequestProcessor2();
if (!connected)
{
rp.OpenConnection2("IMS", "Internal Management System", QBXMLRPConnectionType.localQBD);
connected = true;
}
if (xticket == null)
xticket = rp.BeginSession(cfg.qbfile, QBFileMode.qbFileOpenMultiUser);
As is, this will attempt to launch a new instance of Quickbooks via DCOM, which is not a viable option. Following the QBSDK documention, I attempted to pass null to BeginSession's first argument, which should use the open qbw file.
However, instead of the expected action of connecting to the running instance of Quickbooks, it launches a new instance, eventually yielding the error:
"If the QuickBooks company data file is not open, a call to the "BeginSession" method must include the name of the data file."
The IIS AppPool running the web app uses the same user as the Quickbooks instance I'm trying to connect to.
This was all set up by a third party who is no longer available, and, of course, they left no documentation whatsoever on how this system was supposed to work. Any assistance would be welcome.
I'm trying to help a client who has a web application (ASP/C#) that integrates with Quickbooks via the QBXML SDK.
Unfortunately, this approach will not work.
It's a well-known limitation of QuickBooks that:
QuickBooks has to be running in the user session you're trying to connect from
QuickBooks has to have access to a GUI (it uses a GUI message pump to function)
Because your web app is running in from within IIS, neither of those two criteria are met, and connections to QuickBooks will fail. You should be using the QuickBooks Web Connector instead.
I want to open up a connection to an already active QuickBooks instance in a user session.
Unfortunately, QuickBooks won't allow this.
I managed to create an acceptable workaround to my problem, for anyone trying something similar. (Which, honestly, I don't recommend. I'm working with legacy code here.)
First, a brief overview of my research:
The QBXml interface with QuickBooks uses COM requests in order to communicate. Now, for whatever reason, whether design, bug, or limitation in COM, Quickbooks cannot communicate across LSA Logon Sessions. In practice, this means that the same console session that Quickbooks is running under must also run the QBXml code. Additionally, both Quickbooks and your application must have the same UAC elevation status.
I found no way to get IIS to reliably launch Quickbooks. The individual who setup this system before me managed to do so through some very... unorthodox methods. It was incredibly flaky, and the cause of multiple issues.
Regardless, I did manage an acceptable workaround, in the form of IIS Express. IIS Express can run under a standard user session. As such, running both Quickbooks and the web app (through IIS Express) under the same Logon Session allowed them to communicate successfully.
It is not a permanent solution, as there are drawbacks to running a service such as this in a standard user paradigm, but it is an acceptable workaround, and will allow my client to run their business while we refactor. I plan to first decouple the portions of the app that communicate with Quickbooks, moving them into their own codebase. This will allow the web facing portions of the app to operate in a more standard manner, and communicate with the QB integration code through a more reliable means than COM calls.
Thanks to Keith Palmer for helping point me in the right direction.

CouchDB/PouchDB User Authentication/Authorization

I have been working on an Angular/Ionic application and am using the OAuth.io plugin to handle a facebook login to gain a user's information. From that I derive a simple database name based on the user's firstname and their Facebook ID number.
What I am wanting to do would be to sync this local pouchDB instance to an online CouchDB instance (currently using http://iriscouch.com) for replication to a desktop app, or something similar. The piece I am missing is how to handle user authentication/authorization to be able to only read and write to their own database and no one else's as all of the code currently lives on the client side with no app server to handle any login aside from the OAuth.io plugin.
Is this possible to handle without adding an app server layer, and without manual intervention to create a user on the CouchDB instance?
Currently you can only do per-user read-write permissions in CouchDB by having an additional process on the server side (details), which would be troublesome for you since you're using IrisCouch, so you'd need a separate server somewhere to host this process.
A few alternative options are available to you right now:
Couchbase, which has per-user databases
Janus, which works using Mozilla Persona rather than Facebook ID, and isn't ready yet, but should be unveiled shortly

Implement user authentication against remote DB with a Web Service

I'm just starting reasearch about the best way to implement user authentication within my soon-to-be app.
This is what I have so far:
A desktop (Windows) application on a remote server. That application is accessed locally with a browser (it has a web console and MS SQL Server to store everything).
The application is used with local credendials stored in the DB.
This is what I'd like to accompllish:
Provide access to some information on that SQL Server DB from my app. That access of course must be granted once a user has id himself with valid credentials.
This is what I know so far:
How to create my PHP web service and query info from a DB using JSON.
How to work with AFNetworking libraries to retrieve information.
How to display that info on the app.
What I don't know is which could be the best method to implement user authentication from iOS. Should I send username and password? Should I send some hash? Is there a way to secure the handshake?
I'd for sure appreciate any advise, tip, or recommendation you have from previous experience.
I don't want to just implement it but instead I want to do it as good as possible.
There have been books written on this, so any answer given here is necessary incomplete. So, I'll give you an outline of the simplest thing that actually works. The bare minimum for securing a service like this is to use HTTP Basic Authentication (supported natively by both AFNetworking and PHP) secured by SSL/TLS.
Basic Authentication is a way of hashing (not encrypting) credentials in a standard way and sending them as one of the headers in your request (Authorization: Basic <Base64-encoded concatenated credentials>). AFNetworking supports this as part of its AFHTTPClient class (see the -setAuthorizationHeaderWithUsername:password: method). PHP parses the authentication header into a pair of server variables ($_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW']). From here, you just check the username/password combination against your user database and allow or forbid access to the resource.
The reason it's crucial to pair this technique with HTTPS is that the credential hash is easily reversible; you're basically sending the password in the clear, so it can be grabbed by anyone listening to your traffic. Setting up a certificate and sending your requests over the secure channel prevents this type of vulnerability.
If you want to be a little more sophisticated, two-legged OAuth is also a viable choice for this scenario.

Suggestions for a practical User Authentication System?

I hate to re-invent the wheel so I'm looking for an existing solution to create a simple authentication system for my application. I've experimented for a while with using CardSpace or OpenID inside the application but I can't convince management that these would be working solutions.
Of course, I could just build a simple login dialog where username, domain and (hashed) password is stored inside a database table and I've done such a thing many times already. I hate this solution since I feel it's just a weak option. And I don't want to spend too much time trying to make the whole logon system as secure as possible, especially since I suspect that there should be existing solutions for this.
So, next to OpenID/OpenAuth and CardSpace, are there any other Authentication solutions that can be used from a Delphi/WIN32 application?
Right now, the application will be used by many customers. Most are single-user environments, although it's likely that some of those will start to have two to 5 users once this authentication system is added. But we want to support a customer who needs to allow about 500 different users on the same application. These are spread over about 100 offices but they all connect to the same SQL Server database. (MS Access right now, but we're making it possible for this user to use SQL Server instead.) To make matters even more interesting, the customer uses Citrix to centralize the user systems and the application has straight access to the SQL Server database. It's not an ideal setup but then again, the customer isn't really paying for this. We're just setting up a test environment. A proof-of-concept which the customer will test for us. Flaws will be solved later on. But right now I need quick solutions and one of them is a practical authentication system where I don't have to write a lot of code.
Have you considered using SQL Server authentication and not allowing authentication for those using an Access Database?
If you use the new SQL Server Native Client and SQL Server 2005 you can have passwords expire and change them from your client application. All of the tools to create and manage user accounts are built into SQL Server Management Studio. And if you decide later to support Windows Authentication you just need to modify your connection string.
We have a system where users on the network use Windows Authentication so they don't need to worry about another user name and password. For users that access the system via a VPN and non-domain joined machines they use SQL Authentication.
Here is the MSDN Page that talks about dealing with passwords programmatically in SQL Server 2005
You do need to make sure that SQL Server Native Client is installed, but that is simple compared to the rest of ADO.
I would suggest then
Delphi - since you are using Delphi :)
Open source - since you need to be able to figure out what is wrong if there is a problem, you probably want it cheap.
So, here are some solutions:
http://www.torry.net/pages.php?id=313
CoWindowsAccount v.1.0
SSecurity v.1.2.1.3
http://free-password-manager-plus.software.informer.com/1.6/
It might work for your purposes, but why not ask Windows for the current domain and user name, and use them as unique IDs. Windows has already done the authentication, and it saves the users making up new passwords or anything. I've used this to good effect. I also made it optional to include the machine name in the ID, so that the same user on different computers would also be unique.

Resources