Connecting to Dynamics 365 TDS-enabled database with OLEDB Linked Server - sql-server

I want to run SQL Server queries on a Dynamics 365 database.
The administrators of the Dynamics database have enabled "TDS" for me - and now I can easily connect SSMS, using "Azure Active Directory - Password" authentication, and run SQL SELECTs against it. So far, so good!
But I also wish to create a Linked Server to the Dynamics database, and for this I understand that OLEDB is needed? Is that the correct approach?
Hoping so, I downloaded the latest OLEDB provider, MSOLEDBSQL19. My test query, using OLEDB, looks like this:
SELECT c.*
FROM OPENROWSET(
'msoledbsql19'
, 'Server={myServer};Database={myDatabase};UID={myUserId};Pwd={myPassword};Authentication=ActiveDirectoryPassword;'
, 'SELECT name FROM dbo.account;'
) c;
But this results in the following error:
Failed to authenticate the user 'myUserId' in Active Directory (Authentication option is 'ActiveDirectoryPassword').
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.
A search for "AADSTS65002" brings back "A developer in your tenant may be attempting to reuse an App ID owned by Microsoft. This error prevents them from impersonating a Microsoft application to call other APIs. They must move to another app ID they register in https://portal.azure.com."
I have no knowledge of Azure AD and Dynamics, so this is all a little baffling to me - why would trying a Microsoft OLEDB driver be "reusing an App ID"?
Does a change need to be made at my end, in SSMS that is?
Or is the problem with the Azure/Dynamics configuration? If so I would need to pass details of the solution on to the people administering that.
Thanks for any assistance :)

Related

Access multiple database in Azure SQL

I have created 2 azure security groups (Read-SQL and the second is Write-SQL) in order for them to login into multiple Azure SQL servers via SSMS using their Azure AD identity based on their group membership in order to access multiple databases on those services.
First of all I have configured an admin group on the SQL Server in our Azure tenant.
I have connected to the SQL via SSMS using my credentials and so far so good.
After that I opened a query and typed in master database
CREATE USER [SQL-READ] FROM external provider
ALTER ROLE db_datareader ADD MEMBER [SQL-READ];
(Did the same thing for Write-SQL)
only the user is created and no permission given with an error saying the user does not exist or I don't have permission.
I have Azure global administrator permission in Azure and I don't know why I get this error.
In the bottom line I would like that Read-SQL and Write-SQL will be able to login in to the SQL Server and have access to all databases within it as well as giving Read-SQL reading permissions and to Write-SQL writing permission.
I read a few Microsoft articles but I got even more confused since I don't know if I need to create a login or create a user or a contained user.
Please help
Thank you
Here are few screenshots for better understanding
enter image description here
enter image description here
Read the following articles but only partial success.
https://www.mssqltips.com/sqlservertip/6751/azure-ad-authentication-azure-sql-databases/
https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#create-contained-users-mapped-to-azure-ad-identities
https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-overview?view=azuresql
https://learn.microsoft.com/en-us/sql/relational-databases/security/contained-database-users-making-your-database-portable?view=sql-server-ver16
Whether you should create a login, user or contained user will depend on your access and security requirements. However, in Azure SQL Database, users are created per database. So, you can create the login in the master database and then you need to create the associated user in each database on that SQL Server.
This documentation gives more information on creating logins, users and contained users for Azure SQL Database.

PowerApps allow guest users to connect to Azure SQL database with AAD integrated feature

I have a specific problem to which I couldn't find any answer online.
The situation is the following:
We created a Canvas app that connects to the Azure SQL database. We set the connection type to be AAD integrated.
Users that are members of the AD can see the data in the app, but guest users, even though we gave them all the rights and PowerApps plan, cannot see the data. they recieve the same authorization window as members, but when they click on allow, the app starts but no data is being pulled from the SQL database.
When we try to connect directly to the Azure SQL database with the guest user email and credentials (via SQL server management studio), everything works as expected and the guest can see all the tables.
When we use implicitly shared connection (with SQL server authentification), guests can see the data, but we need to use AAD integrated due to its security.
So far we tried:
Changing PA environment from sandbox to production
Adding special permissions in SQL database like database owner etc
Trying out different AAD guest user settings, eq- setting that guest users have the same privileges as members (picture below).
Nothing seems to work. I would be more than happy if you could tell me how to make this work or even push me in the right direction.
I've reproduced your problem in my side. Here's my experience.
After assigning powerapp license(I use O365 E5 here) to guest account and share the app to this account, I can visit the app but can't see the data in the table. I assume that it resulted from the connector hasn't been shared, but it's true that this connector can't be shared because of no 'share button'.
Then I tried to add access policy to my guest account with these two sql:
CREATE USER [tiny-wa_outlook.com#EXT##xx.onmicrosoft.com] FROM EXTERNAL PROVIDER;
GRANT SELECT ON dbo.tinyTest TO [tiny-wa_outlook.com#EXT##xx.onmicrosoft.com];
Pls note here, I used the User Principal Name here(can find the principal name in azure ad->users), I also tested to use 'tiny-wa#outlook.com' in the sql but after executing successfully, it didn't work.
So I think you can try to use the sql above to add your guests accounts and make them can access the powerapp.
Here's some related docs:
create contained users mapped to azure ad identities
Share app resources
add table permission to user
==========================UPDATE==========================
Share my experience of this troubleshot.
First I need to create a power app but I found that after creating the connector with sql server azure ad authentication, it can't connect to the sql server, the error message is like 'Credentials are missing or not valid. inner exception: The credentials provided for the SQL source are invalid', solution is add my admin account as sql server instance Active Directory Admin.
Then I choose a table and successfully create a sample app. With the creating account, I can visit the app but other accounts can't. Here needs to share the app and it's related connectors to other users. But other accounts still can't reach the app because of no license. Because sql server connector is premium connector, so I assign O365 E3 license here. I met an error when assign license, the user's 'Usage location' can't be null or it can't assign license in M365 admin center.
Then I met similar error with Op, the difference is that both member account and guest account can't see the data in app. I try to find the way to share the connector to these uses but failed, I haven't made sure if those connectors without share button can be shared to others. So I have no options to study if this kind of connectors are authenticated in other ways so they don't need to be shared at all.
Next actions is using the account which used to create the sql server and database to sign in database and execute the sqls above.
Then the member account can see data in the power app while the guest account can't see. The reason is I used xx#outlook.com as the parameter in the sql, when I used xx_outlook.com#EXT##xx.onmicrosoft.com, it worked finally.
Hope this can also help you.
===================================================
For creating my demo app: First, I'm sure my environment isn't a sandbox(the environment in the screenshot below). And I think it's easy to create a demo app, and my app is simple, just choose to create an app from data and then select sql server as the connector, next I choose auzre ad auth and click the connector, enter server name and database name then choose a table, after that my app has created. That table has one row of data so when I signed in the app with the creating account, I see it in the screen while other accounts(member or guests) can't.
My sql server instance and database are created long time ago, but I'm sure I followed this tutorial to create them.
This appears to still be a limitation to access to Azure SQL via PA connector for guest users:
https://powerusers.microsoft.com/t5/Power-Apps-Ideas/Azure-SQL-to-PowerApps-Connector-AAD-doesn-t-work-for-guest/idi-p/1637817
If the "guest" does NOT have a PowerApps Per-App/Per-User plan, they cannot use your PowerApps with SQL data source (Note: SQL is a premium connector).
Determine exactly which type of license the guest has. Then, either your organization or the guest (or guest's org) must purchase one of these licenses. $5/$10/$20 per month depending on your use case.
REF

SQL Server Agent - Untrusted domain message

Running SQL Server 2016. Currently have a solution that is hosted in one domain and of course our access point is in another. we need to pull data in an automated fashion.
We have added a windows credential with the credential manager which collects endpoint information and a set of credentials.
e.g.
Internet or Networkaddress: mydatabase.remotedomain.com
Username : remotedomain\username
Password : password
This solution works with many tools, Excel, SSMS direct query, Visual Studio. The user enters the endpoint (server url or IP/port) and uses windows integrated security. the connection is made and credential store does the trick and user is authenticated.
SSMS example
Server name: mydatabase.remotedomain.com
Authentication: Windows Authentication
My challenge is SSIS and SQL Agent. The SSIS package runs in VS2015. deploy the package to Integration Services Catalog - highlight package and execute and it runs.
Create a SQL Server Agent Job and execute the job and I receive this gift.....
Login Failed: The login is from an untrusted domain and cannot be used with Windows authentication
I have created a SQL credential, created a Proxy (SSIS Package Execution), created a job that uses the Run As with the Credential but this ends with the same result. The credential has to be in my local domain or the job wont run....and of course localdomain\username does not authenticate against the remote data connection. So Proxy does not help the situation.
What I was expecting is that the windows credential manager would swap the credentials as it does when the job is run manually, or through excel or a number of any other ways...
I opened a ticket with Microsoft and worked with one of their senior resources on this.
this appears to be a bug in SQL Agent. There is no known reason or issue that prevents SQL Agent from picking up the remote credential from the Windows Credential Store, but it is not.
A working alternative was to use the command line utility DTEXEC. some slight modification to the SSIS project to make sure all connection managers are at the package level instead of project (created a reference issue).
this solution is not ideal, but it worked and DTEXEC allowed SSIS to pickup the required credential in the store and execute without issue.
I will follow up once Microsoft completes their research and gets back to me, the ticket is still open.
Sorry but changing the group to Global or Universal for the local AD account is not having any effect. I am bit lost on how making a change on the local account in use for SQL Agent will make any difference. The solution works in all the tools by local account substitution with the remote account setup in Credential Manager. If I missed it, and making this change should work, please provide an example of the setup if possible.
Again it appears this process is not being executed/followed by SQL Server Agent since it works everywhere else but not in a job executed by the Agent.
so again my hope is somebody has seen something like this before and has a solution.
my end goal is to just automate pulling data from a remote SQL server where there is no trust. I was hopeful that the proxy solution would work, but when you set the credentials to the remote domain\username, the job wont even execute.
Is there a way to setup my connection in the SSIS package to expressly set the credentials to the remote domain\username\pwd. I took a stab at that and couldnt get that to fly either. if so, an example is priceless to me.
I dont care how i get to the goal line, just need to...thanks all for the help
Your window credential account should be an AD user account which is in a Group with a scope of either Global or Universal. Universal groups are useful where you have multiple domains.
The process will execute in whatever context it's called in (i.e. by you, SQL Agent, or the proxy account). It doesn't change executable context as it calls different processes, unless you pragmatically make it, and that's bad idea anyway...
Had similar issue and it was a nightmare to resolve! Learned a lot of fun AD configuration tips along the way.
Understanding User and Group Accounts states the following:
Groups can have different scopes—domain local, built-in local, global, and universal. That is, the groups have different areas in which they are valid.
Global groups:
Groups that are used to grant permissions to objects in any domain in the domain tree or forest. Members of global groups can include only accounts and groups from the domain in which they are defined.
Universal groups:
Groups that are used to grant permissions on a wide scale throughout a domain tree or forest. Members of global groups include accounts and groups from any domain in the domain tree or forest.
EDIT
If it's just a data pull from one domain to another, can the data be first exported to a csv in the untrusted domain and then SFTP'd into your environment where the TL(Transform and Load) of the ETL(Extract-Transform-Load) process could take place?
SSIS would be a good tool for this, but C# and Powershell could also be used.

SQL Server Integrated Security

I've been searching hard to get my head around security related issues in a SQL Server.
We're developing a .NET application that targets SQL Server 2008 and we want to use FileStream.
Now I've found out that SQL Server only allows FileStream through the Win32 API if you use Integrated Security. The problem is that we have around 80% of our application finished, but it is entirely based on SQL Authentication. So we are doing INSERT's straight form our application and are not using Stored Procedures for every CRUD operation.
This is relatively safe because I can store the the SQL username and password in an encrypted form. I know the password is transported in Clear Text, but I'm willing to accept that.
We want end-users to be able to connect to the databse through tools such as Crystal Reports and for that we have an extra SQL login that has only SELECT-rights granted.
Now, if we change to Integrated Security we would have to give individual users (via AD groups, etc.) rights to do the things the application can do. Otherwise the application would not be able to do it's work. But then the end-user would also have these rights when he connects straight to the DB.
I see people saying that you should use Stored Procedures for every CRUD operation and grant the EXEC-rights only to the AD-group, but how would I do this? I do not see how a user would have different authorizations when he connects directly or through the application... Can anybody enlighten me on this.
An extra question for bonus-points: Intergrated Security will not work on a Workgroup as far as I understand. How do people get FileStream to work in a Workgroup then? Or is this considered an impossibility?
Integrated security WILL work in a workgroup, using the legacy mechanism, where you have a matching username and password on the two machines. Also, a domain user can use the legacy mechanism to log into a non-domain server if the server has a matching user account.
Integrated security can even work with non-matching usernames and passwords. This may help you in your scenario.
Try this:
NET USE \\DBSERVER /USER:DOMAIN\USERNAME
You will be prompted for your password. This establishes a NetBIOS session with the database server. You should be able to see the shared folders and shared printers on the database server once you have done that.
Once a netbios session has been established between the client computer and the database server, you will THEN be able to use integrated security without being prompted for a password.
You may have to specify "named pipes" as the network protocol to usem, if it doesn't work with TCP (but I think it will). Named Pipes inherits your existing NetBIOS session, so provided you can list the shares you are probably good to go.
You can also establish the logon session using the windows API function NetUseAdd with USE_INFO_2 (level 2) information which incorporates the password.
I guess the short answer then is that you can have a special Windows logon for your application and have the users log in using that. However note that they cannot also be connected to the same server using their own username and password.

Add IIS 7 AppPool Identities as SQL Server Logons

I'm running an IIS 7 Website with an AppPool of Integrated Pipeline Mode.
The AppPools does NOT run under NetworkService, etc.. identity (by purpose), but uses its own AppPool Identitiy (IIS AppPool\MyAppPool).
This is a so called service account or virtual account.
(a user account, which is not a full account...)
I'd like to give this service account (IIS AppPool\MyAppPool) permissions to connect to my SQL Server 2008 Express (running in Mixed Auth. Mode).
While SQL Server can add any normal user account, the IIS AppPool\MyAppPool virtual account cannot be added to the valid logons (SQL Server says, that the account cannot be found).
Is there any trick, anything I need to enable to make the virtual accounts work?
(the w3wp.exe process runs under this identity according to taskmgr, but I cannot use the account in NTFS security either...)
Thanks for your help!
The "IIS APPPOOL\AppPoolName" will work, but as mentioned previously, it does not appear to be a valid AD name so when you search for it in the "Select User or Group" dialog box, it won't show up (actually, it will find it, but it will think its an actual system account, and it will try to treat it as such...which won't work, and will give you the error message about it not being found).
How I've gotten it to work is:
In SQL Server Management Studio, look for the Security folder (the security folder at the same level as the Databases, Server Objects, etc. folders...not the security folder within each individual database)
Right click logins and select "New Login"
In the Login name field, type IIS APPPOOL\YourAppPoolName - do not click search
Fill whatever other values you like (i.e., authentication type, default database, etc.)
Click OK
As long as the AppPool name actually exists, the login should now be created.
CREATE LOGIN [IIS APPPOOL\MyAppPool] FROM WINDOWS;
CREATE USER MyAppPoolUser FOR LOGIN [IIS APPPOOL\MyAppPool];
You can solve like this,
Open "Applications Pools",
You should right click that you have choosed application pool. Then choose
"Advanced Settings".
Click three point on the Identity tab then you should choose "LocalSystem" from field of "Built-in-account"
If you do this way, you don't need to create a user in database.
If you're going across machines, you either need to be using NETWORK SERVICE, LOCAL SYSTEM, a domain account, or a SQL 2008 R2 (if you have it) Managed Service Account (which is my preference if you had such an infrastructure). You can not use an account which is not visible to the Active Directory domain.
As a side note processes that uses virtual accounts (NT Service\MyService and IIS AppPool\MyAppPool) are still running under the "NETWORK SERVICE" account as this post suggests http://www.adopenstatic.com/cs/blogs/ken/archive/2008/01/29/15759.aspx. The only difference is that these processes are members of the "NT Service\MyService" or "IIS AppPool\MyAppPool" groups (as these are actually groups and not users). This is also the reason why the processes authenticate at the network as the machine the same way NETWORK SERVICE account does.
The way to secure access is not to depend upon this accounts not having NETWORK SERVICE privileges but to grant more permissions specifically to "NT Service\MyService" or "IIS AppPool\MyAppPool" and to remove permissions for "Users" if necessary.
If anyone has more accurate or contradictional information please post.
Look at: http://www.iis.net/learn/manage/configuring-security/application-pool-identities
USE master
GO
sp_grantlogin 'IIS APPPOOL\<AppPoolName>'
USE <yourdb>
GO
sp_grantdbaccess 'IIS APPPOOL\<AppPoolName>', '<AppPoolName>'
sp_addrolemember 'aspnet_Membership_FullAccess', '<AppPoolName>'
sp_addrolemember 'aspnet_Roles_FullAccess', '<AppPoolName>'
This may be what you are looking for...
http://technet.microsoft.com/en-us/library/cc730708%28WS.10%29.aspx
I would also advise longer term to consider a limited rights domain user, what you are trying works fine in a silo machine scenario but you are going to have to make changes if you move to another machine for the DB server.
I figured it out through trial and error... the real chink in the armor was a little known setting in IIS in the Configuration Editor for the website in
Section: system.webServer/security/authentication/windowsAuthentication
From: ApplicationHost.config <locationpath='ServerName/SiteName' />
called useAppPoolCredentials (which is set to False by default. Set this to True and life becomes great again!!! Hope this saves pain for the next guy....
In my case the problem was that I started to create an MVC Alloy sample project from scratch in using Visual Studio/Episerver extension and it worked fine when executed using local Visual studio iis express.
However by default it points the sql database to LocalDB and when I deployed the site to local IIS it started giving errors some of the initial errors I resolved by:
1.adding the local site url binding to C:/Windows/System32/drivers/etc/hosts
2. Then by editing the application.config found the file location by right clicking on IIS express in botton right corner of the screen when running site using Visual studio and added binding there for local iis url.
3. Finally I was stuck with "unable to access database errors" for which I created a blank new DB in Sql express and changed connection string in web config to point to my new DB and then in package manager console (using Visual Studio) executed Episerver DB commands like -
1. initialize-epidatabase
2. update-epidatabase
3. Convert-EPiDatabaseToUtc
For the ApplicationPoolIdentity, add a login/user in MSSQL as IIS_IUSRS which is corresponding to the default pool.

Resources