Access Dynamics 365 database from third party application - sql-server

I'm trying to access the SQL Server database behind our Dynamics 365 installation. There's a nice step-by-step guide how to do that here:
https://dynamics-chronicles.com/article/how-access-dynamics-365-online-sql-server-database
I followed all steps and can easily connect from SQL Server Management Studio. Very, very cool!
However when I try to use a third party app to go the same way to access the server, I get the attached error message, saying the this app must be preauthenticated somewhere. But I don't understand how to do that and what that means?
Can someone point me in the right directions?
It looks like the app is submitting some kind of identifier that must be white listed somewhere?!

I get this error too with the OleDb provider.
PS C:\Users\david> $con.open()
Exception calling "Open" with "0" argument(s): "Failed to authenticate the user 'dbrowne#microsoft.com' in Active
Directory (Authentication option is 'ActiveDirectoryInteractive').
Error code 0xCAA20002; state 10
AADSTS65002: Consent between first party application 'db465503-d247-463e-8a13-95889346b742' and first party resource
'00000007-0000-0000-c000-000000000000' must be configured via preauthorization - applications owned and operated by
Microsoft must get approval from the API owner before requesting tokens for that API.
Trace ID: fc6fc7d2-1c95-431f-861e-db45297c3500
Correlation ID: 0b0fb2f8-248f-489a-9ed1-a4584b9d8d12
ODBC works, though (I had to use ActiveDirectoryInteractive because MFA is required in my tenant).
PS C:\Users\David> $con2 = new-object system.data.odbc.odbcconnection
PS C:\Users\David> $con2.connectionstring="driver={ODBC Driver 18 for SQL Server};server=xxxx.crm.dynamics.com;authentication=ActiveDirectoryInteractive;UID=xxx#yyy.com"
PS C:\Users\David> $con2.Open()
If you have to use OleDb you can use MSDASQL, the OleDb provider for ODBC to use this ODBC driver from an OleDb client.

Related

Docker .NET Core API connection to SQL Server through Kerberos

Someone have success to connect a Dockerized .NET Core API 2.2 with SQL Server located in external client cloud server through Kerberos?
Here we're facing these issues:
Scenario 1:
If we use a connection string like this:
Server=tcp:SERVER_IP_ADDRESS,1433; Database=DB_NAME; User Id=USER; Password=PASSWORD;
then, it takes a long time and throws the exception like this:
SqlException: A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - Success)
Scenario 2:
If we use a connection string like this:
Server=tcp:SERVER_IP_ADDRESS,1433; Database=DB_NAME; User Id=USER; Password=PASSWORD; Trusted_Connection=True;
then, the exception is:
SqlException: Cannot authenticate using Kerberos.
Ensure Kerberos has been initialized on the client with 'kinit' and a Service Principal Name has been registered for the SQL Server to allow Kerberos authentication.
ErrorCode=InternalError, Exception=Interop+NetSecurityNative+GssApiException: GSSAPI operation failed with error - Unspecified GSS failure.Minor code may provide more information (SPNEGO cannot find mechanisms to negotiate).
So, our hands are tied and we don't know where to run.
Can u help us?
Thanks in advance.
If you don't need strictly kerberos to authenthicate, just use sql user nad password.
To do that create a user on sql server only (not in windows, use ssms to do it or sql script) and use that user, not the windows one.
It seems that you don't use sql server authentication, at least you don't use sql server user but a windows one and sql server tries to authenthicate that user in AD instead authenticating it locally on sql server.
However if you want to use Windows auth, you probably would need to use windows containers and gMSA accounts, see https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/gmsa-run-container

IIS Connection IIS Basic User Settings Specific User Cannot Connect to SQL Server using Perl DBI

My Perl IIS web application is getting an SSL Error when the Perl DBI tries to connect to my MS SQL Server database version 11.0.7001 (that's what is listed in SQL Server Manager). The Perl application runs under IIS, and my IIS Basic User Settings Connection is set to Specific User (Domain Administrator).
The SQL Sever database resides on the same system as IIS. The distribution of Perl is Strawberry Perl; IIS' version is 8.5.9600.16384.
I can connect to the database using the SQL Server Manager locally on the server as well as remotely from my workstation. The connection type is SQL username and password. The IIS application listens on port 8085. The IIS permissions are not restricted, and there is no SQL server connection string as part of IIS.
The first page of the application loads, but this first page does not try to connect to the SQL Server database.
I have been looking at Stackoverflow posts -- like this one -- for a while, and have tried some of the suggestions like making a system DSN (which tests correctly), instead of a DSN string in Perl.
None of the suggestions have helped, and many but not all of the posts are dealing with security and certificates, not an application that is behind a firewall. In other words, I do not have security turned on.
To the best of my knowledge there is no security turned on for this application, and Named Pipes and TCP/IP were already turned on, as was suggested in one of the posts I read.
Here is the error:
[Microsoft][ODBC SQL Server Driver][DBMSLPCN]ConnectionOpen (SECCreateCredentials()). (SQL-01000) at ../../include/DbArgs.pm line 266.
DBI connect('driver={SQL Server};server=arlsql\arlsql;database=BuildingPermit;uid=user;pwd=pwd','',...) failed: [Microsoft][ODBC SQL Server Driver][DBMSLPCN]SSL Security error (SQL-08001) [state was 08001 now 01000]
Any suggestions on what to try next would be appreciated.
Edit 1/6/2020
I need to add that my C# client application using .Net ODBC objects successfully accesses the same database on which the web-based Perl DBI code fails. The username and password are the same for the client application as that used in the Perl CGI.
The IIS user for this application runs as the domain administrator, but when creating the DBI connection uses the same username and password. The database is set up for SQL username and password, and, as stated previously, there is no security set, at least that I can tell.
This does not answer the question but is instead a workaround. I consider the following a workaround, because I would still like to know why the DBI call failed with a specific user.
I switched my IIS Basic User Settings Connection from Specific User (Domain Administrator) to Application User (pass-through authentication).
After making this change and restarting IIS, the Perl DBI connection worked, but why?

SQL Server log in failing from Java DriverManager.getConnection(), working from Python with pymssql.connect()

I'm trying to use DriverManager.getConnection() to connect to a SQL Server db from a Java application, but I keep getting "Login failed for user" errors with it. I've tried using both com.microsoft.sqlserver.jdbc.SQLServerDriver and net.sourceforge.jtds.jdbc.Driver to connect, but both keep hitting the issue.
Here's the code I'm using to connect:
Class.forName("net.sourceforge.jtds.jdbc.Driver");
conn=DriverManager.getConnection("jdbc:jtds:sqlserver://SERVERADDRESS:1433;DatabaseName=DBNAME;user=USER;password=PASS");
I know that account has access to that DB, as I've connected to it before from a Python application using pymssql.connect(SERVERADDRESS, USER, PASS, DBNAME) with the same server/DB/creds.
From this article, I eventually managed to get it working using windows authentication with my personal account, but I still can't get it to work using our service account. Does anyone have any insight into why the Python app can connect but the Java one can't?
pymssql is built on top of FreeTDS. Both FreeTDS and jTDS support an older Windows authentication scheme named NTLM, while current versions of Microsoft's JDBC Driver for SQL Server (mssql-jdbc) no longer support that authentication mechanism.
So, given that you've confirmed that pymssql can connect, you should be able to connect from your Java app as Windows user MYDOMAIN\username using jTDS like so:
String myUid = "username", myPwd = "mypassword";
String connUrl = "jdbc:jtds:sqlserver://192.168.1.123:1433/databasename;DOMAIN=MYDOMAIN";
Connection conn = DriverManager.getConnection(connUrl, myUid, myPwd);
To find out the reason of "Login failed for user" one should go to SQL Server error log.
The next row to 18456 error will give you the reason.
The most probably reason of failure in your case is that the server is configurated to use Windows Authentication only

Authenticating to a SQL Server instance as a Windows User via JDBC

I'm having to support multiple database types for my tenant-enabled web application. Among others, I have successfully supported Microsoft's SQL Server, by using the net.sourceforge.jtds.jdbc.Driver class with a connection String like "jdbc:jtds:sqlserver://192.168.1.189:1433/ApplicationName". This works, but it requires that the user explicitly defines a user in the SQL Server instance and enables SQL Server authentication.
Now, inevitably, requirements changed, and we're supposed to support connecting to SQL Server via Windows Authentication. Evidently this requires some sort of change to the connection string, since the data base server must somehow be able to distinguish whether the credentials passed into the data base connection are for a user defined in the SQL Server installation or in the Windows OS. But what is it?
Acting on advice from the internet, if progressed as far as extending the connection string with ;useNTLMv2=true;domain=WORKGROUP. That seems to make the data base server aware that I want to authenticate as a Windows user, but the actual log-in fails with
The login is from an untrusted domain and cannot be used with Windows authentication. (code 18452, state 28000)
Now im my testing set-up, both the J2EE app and the SQL server instance are in fact on the same machine (although in production they may not be), and still this computer isn't trusted enough to log on to itself? Evidently I'm missing a big part of the puzzle here. What does one have to do to convince an SQL Server instance that the user who started it can in fact log on to it via JDBC?
Edit
Since we have already sunk too much unsuccessful effort trying to integrate our web application with a full Microsoft infrastructure stack (SQL Server, Active Directory, Domain Name Service...), I have to restrict this question:
Does anyone know a way to access an SQL Server installation with a user account defined as a "Windows User" via JDBC form a J2EE application, without having to use Active Directory, a Windows machine running the web application and a proprietary DLL? The bounty is for any solution of that sub-problem. The entire problem is clearly too broad to be answered in one forum post.
I ran into the error
The login is from an untrusted domain and cannot be used with Windows
authentication
when a 2012 SQL Server DB instance was recently upgraded to 2016. In order to use AD based authentication with the JTDS driver and SQL Server 2016, it seems necessary to specify both the useNTLMv2=true and the domain=example.com suffix in order to establish a connection. The name of the domain is absolutely necessary and I confirmed that through testing. This is with JTDS driver version 1.3.1.
Example of a working connection string using AD based authentication to SQL Server 2016 DB with JTDS 1.3.1:
jdbc:jtds:sqlserver://sqlserver2016db.example.com/MY_DB_NAME;domain=example.com;prepareSQL=2;useNTLMv2=true
UPDATE
Recently (due to the pandemic lockdown), I found myself also having to connect to SQL Server using Windows authentication from a non-domain computer (over VPN). This can be accomplished by starting the Windows process initiating the SQL Server connection, e.g. Eclipse / Spring Tool Suite, with the following command:
C:\Windows\System32\runas.exe /netonly /user:domain\user "path_to_executable.exe"
Source: https://www.mssqltips.com/sqlservertip/3250/connect-to-sql-servers-in-another-domain-using-windows-authentication/
In discovering that gem, I also discovered that encryption needed to be used. Here are the settings I'm using (in addition to now running the executable with /netonly and a domain account):
spring.datasource.url=jdbc:jtds:sqlserver://fqdn_of_server_including_domain/DBNAME;domain=mydomain;useNTLMv2=true;ssl=require;prepareSQL=2;
spring.datasource.username=domainaccountname_without_domain_prefix
spring.datasource.password=password
spring.datasource.testOnBorrow=true
spring.datasource.hikari.connection-test-query=SELECT 1
spring.jpa.database-platform=org.hibernate.dialect.SQLServerDialect
What you describe certainly appears to be feasible. I have SQL Server 2008 R2 Express running on a stand-alone server and I was able to connect using a Windows username/password on that server via jTDS 1.3.1 from a separate Windows machine and from an Xubuntu 14.04 box.
On the machine running SQL Server I created a Windows user named 'kilian'. In SQL Server itself I created a SQL Login for NT AUTHORITY\Authenticated Users. Then in the database (named 'myDb') I created a User named 'AuthenticatedUsers' for that SQL Login. Just to keep things simple I gave that user db_owner rights on the database.
There is no SQL Login for 'kilian' and no database User with that name.
Then, from the other two machines (the Windows workstation and the Xubuntu box) I just ran this:
package com.example.jtdstest;
import java.sql.*;
public class JtdsTestMain {
public static void main(String[] args) {
try (Connection con = DriverManager.getConnection(
"jdbc:jtds:sqlserver://192.168.1.137:52865/myDb" +
";domain=whatever",
"kilian",
"4theBounty")) {
try (Statement s = con.createStatement()) {
String sql = "SELECT LastName FROM Clients WHERE ID=1";
try (ResultSet rs = s.executeQuery(sql)) {
rs.next();
System.out.println(rs.getString("LastName"));
}
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
Additional notes:
I did not have to include useNTLMv2=true. I was able to connect with or without that parameter.
I did have to include domain= to tell the SQL Server not to use SQL authentication, but the actual value I supplied made no difference. (I literally used 'whatever', which was not the name of the server or the name of the workgroup to which it belongs.)
Alternative Method
The alternative solution is to utilize integrated security. This enables your application to connect to the database as the user in which the application is currently running as. This is enabled by adding integratedSecurity=true; into the connection string properties. If you run into any trouble, make sure the sqljdbc_auth.dll is accessible via classpath or within your app library.
Security Note
You're probably already aware, but just have to say make sure not to grant access to "Authenticated Users" to your database as previously suggested as part of the demonstration. Identify which user account your application runs as and grant access to only that specific user in your database server.
Sources / Additional Info
MSDN Doc on JDBC Connection String Configuration (http://technet.microsoft.com/en-us/library/ms378428(v=sql.110).aspx)
The main problem is the windows authentication with a full java solution (no DLL). So you could use one of the libs below:
NTLM authentication: http://ioplex.com/jespa.html
spring based Kerberos authentication: http://projects.spring.io/spring-security-kerberos/
another integrated windows auth lib is SPNEGO (don't know much about this one)
So once your app is authenticated with one of the lib above, your JDBC should run fine using "integratedSecurity=true;" and if needed "authenticationScheme=JavaKerberos".
Firstly you should write the jdbc connection like this:
String url ="jdbc:sqlserver://PC01\inst01;databaseName=DB01;integratedSecurity=true";
then
you need to enable the SQL Server TCP/IP Protocol in Sql Server Configuration Manager app. You can see the protocol in SQL Server Network Configuration.
I can see two possibilities,
1. You are using a local system account which the server won't understand
In this case, switch to a domain account.
Windows authentication has different credential requirements and you might not be meeting those.
In this case try changing the password to match the requirements.
It is very well possible that both are happening.
see this other SO post that describes how to connect to a SQL Server with Windows Authentication from a Linux machine through JDBC
This is my NiFi setup for jTDS driver:
Database Connection URL: jdbc:jtds:sqlserver://192.168.1.189:1433;DOMAIN=domain_name
I didn't need to add useNTLMv2=true, but most people need to, so if it doesn't work you can try also:
jdbc:jtds:sqlserver://192.168.1.189:1433;DOMAIN=domain_name;useNTLMv2=true
Database Driver Class Name: net.sourceforge.jtds.jdbc.Driver
Database User: domain_user_name (**without** #domain)
Password: domain_password
Validation query: select 1
One of the possible reasons for this error to appear is when you configure you data source to use windows authentication and SQL Server is using Extended Protection mode together with SSL (i'm not sure if SSL is required though). This mode requires the client to send additional information - signed service principal name (SPN) and channel binding token (CBT). See more information about Extended Protection Mode here. Currently both JTDS JDBC and Microsoft JDBC drivers do not support this mode. I couldn't find an official statement from JTDS, but there is an open ticket for Microsoft drivers.
In order to configure Extended Protection mode, go to SQL Server Configuration Manager, select properties on SQL Server Network Configuration -> Protocols for %your instance% and change Extended Protection option.

How to Write data to Sql Table from SharePoint WebPart when DB and SP are on different machine?

I am working on SharePoint 2013. Database is on SqlServer 2008R2. Both SP and DB are on different machines. I am creating a webPart which is associated with usercontrol. I'm writing the logic in cs file of usercontrol, to write data collected from the form into Data table of sql server.
Connection string: Server=myServerAddress;Database=myDataBase;User
Id=myUsername; Password=myPassword;
But it is failing and throwing an error like "Login failed for user".
Please guide.
You may be running into the Double Hop Problem (also see why NTLM fails). To know for sure use ULSViewer to drill into the SharePoint Error details. From the SQL side check the default trace. "default trace gives you the reason for login failure in plain English"
If it is the double hop causing the error, you may want to look into configuring Kerberos or switching to using an External List instead of a web part and using the Secure Store Service with BCS.

Resources