Using SQL 2019 Always Encrypted Columns and MVC.NET with IIS 10 need to validate if domain users have certificate installed on their local machines
Steps already done but not working
Create Master Key saved into database Server local machine certificate
Grant IIS_IUSRS read permission to read private keys of certificate
Change application pool user to run using Network Services
Access application from URL with user doesn't have certificate and data shown as plain text
Is there any way to make sure that only domain users with valid certificate (using export and import from MMC) will see data as plain text?
Related
Background: I built a Razor Pages web app that connects to Azure SQL DB and have successfully set up Azure AD single sign on. I have a DB context class which use AD interactive authentication, but when I publish the app to the Web App Service, I have to configure the Azure SQL DB dependency and I am forced to hard-code a username and password.
I have created users and logins in the DB and also utilize RLS as not all users have a need to see all data in certain tables, so I want to retain the security measures already in place.
Problem: Because the username and password are hard-coded all users will be able to see, edit, delete information they shouldn't, so I need to configure pass-through authentication to the DB.
Anyone have examples on how to achieve this?
Edit: Just how you can configure Power BI to have end users use their own credentials to access the SQL DB, I need to this with my web app.
If you want to protect the username and password, some other way is that you can store the SQL database connection string to the Azure Key Vault, then use secret key name to connect to the SQL database.
Example ref: Spring boot application that would read configuration from Key vault and connect to SQL?
I have purchased an SSL certificate and installed it using IIS on my remote system. So I can therefore access my remote system using https://myremotesite.co.uk. All is fine, it seems to work; users can register and login to my remote site and download my GUI to run my application which stores and retrieves data from my SQL Server database.
When a user runs my GUI to access my application it prompts them for their login-id and password and, if they are authenticated, my application pops up on their screen. All is well, it all seems to work fine.
However, I have read that access to the SQL Server database itself can be restricted with an SSL certificate and to do this I would need "Encrypt=yes" in the connection string which my GUI uses to check authentication.
Is it necessary for me to do this? Or is safe to just rely on the IIS HTTPS service? So my question is ... do I need to register my SSL certificate with BOTH IIS AND SQL Server or just ONE of them, and if so, which ONE?
Thanks for the answers thus far .. to explain further, the GUI connects to an IIS controlled website which has specific handlers written to perform a restricted set of database queries. So my database DOES reside on my server, but it only allows my server's (local) IIS to 'login' and insert, update and extract data.
Once the IIS website service has extracted data, it then returns the same to the GUI. So the GUI has no DIRECT access to the database. What I am concerned about is if - by some malicious means - the database was copied in its entirety ... could/should I use my SSL certificate to encrypt sensitive data in this event?
To express myself better i start by example.
In my client server application there is a users table.
Each user is mapped to a sql server user.
The database is full of tables, anyway each user can query just 1 table.
The table contains the following information:
the version of the database (so the client app can check whether the database version matches with the client version)
the db admin login name (tipically "sa")
the db admin password (this is encrypted with custom algorithm for security - please note i install a dedicated Sql Server Instance for my applciation)
I make sure each user can query just a table by executing for each user:
GRANT SELECT ON ConnectionTable TO LoginName
So the full flow is:
1) the user inserts username/password
2) the client application retrieves all the info from ConnectionTable
3) the client applicaion decrytpts the sa password
4) the client application logs in as sa so all tables are visible and editable
Now this is what i have (legacy) and I cannot change it.
Somehow this "custom login trick" has been done to avoid to write somewhere on the client the sa password, many client server software i know in fact all use sa to connect and user/password are just two fields of a simple USERS table, but the real connection string is somehow (with a certain degree of security) saved on a file in each client; in my case the "connection string" is stored in the database so as a user logs in to the database (even if with a user that has a restricted access) he gets all he needs to succesfully login.
Since i install Sql Server in mixed mode i support also Windows AUthentication.
So at login the user has a switch to choose between SQl Server and Windows Authentication, as it happens when connecting to SS Management Studio.
What i am trying to achieve now is to login as another user.
I would like that the user checks "Windows Authentication" but he/she can still type the username and the password.
My application is written in Delphi using the SDAC components. As far as i understand SDAC does not allow to perform what i need to do, but i could change only the login part using anothe DAC (Firedac for example). My goal is to login as another windows user.
The final goal is to query ConnectionTable so that i can retrieve the encrypted sa password and login.
So my question is:
is it possible (in Delphi Seattle VCL Application) to login to a Sql Server database by setting a windos user different than the current logged in user?
UPDATE:
To better explain my need i describe the real scenario that generates my requirement.
I created a web applciation (using VCL for the web) that uses the same authentication method as my client server application does.
Imagine my user is MyDomain\MyUser, when I am in LAN i will use Windows authentication to login, but when I login let's say from my Android Phone I would like to login as MyDomain\MyUser by providing password. This is the case, in fact i do not need to impersonate other users, i just want to login with my user when i am not logged in on a Windows pc in a LAN.
So somohow at the login screen of my application i would like to choose Auth: Win/SQL and in case Win is chosen, i would like to pass the actual username and password to login.
I hope this clarifies more the scenario.
Moreover i also host my application in the cloud and in this case all users are WIndows authentication users of a domain that i created for administratrive purposes, and each user needs to provide username and password to login.
My request comes from the fact that I always supposd that Winows Authentication = LDAP and therefore in LDAP it is possible to specify user and password, while in sql server it looks somehow user is pre-defined (and = to the logged in user) in case of Windows authentication.
The conventional wisdom says using your Windows user to login to SQL Server is more secure than using a SQL Server user to login. But isn't the authentication nearly identical?
When you login to SQL server with a database user, a login packet is created with the password encrypted. A certificate is attached to the packet and sent to the database. When the certificate is authenticated, the hashed password is matched to the hashed password stored in the database. If they match, you are logged in.
When you login to SQL server with a Windows user, MSGINA creates a login packet, but I'm not sure if or how it's encrypted. A certificate is attached and the packet is sent to LSA. When the certificate is authenticated, how are the credentials verified?
To make this question fair, assume the certificate service is the same, as well as the method to create the password hash. In this scenario, the two methods seem equally vulnerable to a man-in-the-middle type of attack intercepting the login packet.
Depends how you define "secure". There's more to security than the cryptographic details of the authentication mechanism. For example:
With SQL Server auth, accounts/passwords are under the control of the DBAs. With Windows auth (to a domain) they're under the control of the domain admins.
Security policy (e.g. password strength, password aging, password length, permitted login locations/times, disabling accounts) is readily administered (e.g. via group policy) and audited when using domain authentication.
Domain authentication can use multiple factors (e.g. security tokens), whereas SQL Server authentication (AFAIK) can't.
MITM vulns in AD authentication (and more broadly Kerberos in general) would be big news.
Windows login is very secure - assuming Active Directory, you're sending a hash to AD to authenticate you which returns the ticket that is subsequently used to login to SQLServer.
However, this only applies to AD, local users use NTLM which is pretty old and is easily crackable by today's standards.
Windows logins are used to secure pretty much everything, including the user services like SQLServer runs as, so if its not the most secure then you have more worries than user login to your DB.
The question is how you store the password and login information.
When you use Windows-login you can rely on authentication by your active directory server or simply the windows machine, while when login with SQL Server credentials you will need to have the password somewhere in a form that you'll need to encrypt it in order to add it to the connection string.
This might be fine if the application is on the server, but more complicated when it is a rich client which is accessing the server directly. If you have such a scenario in a company, it is better to let active directory deal with the authentication.
In general it is also easier to administrate when you have the same active directory use everywhere.
is it possible to use a database created in a Azure VM as a data source for model which is created in Azure Analysis Services?
So far, when I specify connection properties for the model in the web designer and test connection, I get an error stating "a connection was successfully established with the server, but then an error occurred during the login process. (provider SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)
I can connect to the server via SSMS and via RDP.
I created a self-signed certificate in the azure key vault and was able to make the SQL server use it. However I can't seem to find out how to make use of it when connecting the model.
Does anyone know if it's possible and if so, what should I do to make it work?
In the end I managed to make it work. For anyone with similar problem, I will write my solution below.
For the error "The certificate chain was issued by an authority that is not trusted" - just as discussed in the thread linked by TJB in comment, this was because I did not have a CA signed certificate, but a self-signed one.
A CA signed certificate from Azure would probably solve the issue, but I tried the Let's Encrypt site (also linked in the other thread). The issue I had with Let's Encrypt was that I had a windows server, while they natively support linux-based systems.
However I found an article by Daniel Hutmacher called Encrypting SQL Server connections with Let’s Encrypt certificates which was solving the very issue I had.
(as for the client tool, the current version is different from the one described in the article, but you can still download the old version on github. I used the lastest november 2017 release). With this I was able to generate and add a CA signed certificate to SQL server.
At this point, I created a model in Azure Analytics Services, used Azure Database as type of source/connection and filled in the connection to my VM SQL server. I saw my database tables, but when I tried to query data, I got a new error, stating that the AAS need an On-premise data gateway set up.
The Microsoft docs Install and configure an on-premises data gateway describes how to install on-premise data gateway on the VM, but if you are like me and use personal account for azure, you will have issues binding your account to the gateway. The solution as hinted here is to create a new account in Azure Active Directory (I created a new user and registered it under my azure custom domain, so the login looked like XXX#zzz.onmicrosoft.com). I gave the user admin role, so as to temporarily avoid any azure permission setbacks. Next I added the user to my subscription via Subscriptions -> "My_subscription" -> Access Control (IAM) and assigned an owner role to the AD user.
Now back on my VM I could bind the new user's account to the gateway (don't forget to change the gateway's region to your preferred region before finishing the setup).
Next, on Azure I created an "on-premise data gateway" service (do note you need to select same region as the one which your VM gateway is located under). I am not sure now, if only the new AD user I created could see the gateway, so in case you do not see it, try the AD user as well.
Last but not least, in the Azure Analytics services I went to the "on-premises data gateway" settings and set it to use the one I just created.
With this I was able to create the model and query the data from database.
Note:
In the model web designed for analytics services I happened to be logged in under the AD user, not under my personal account. Attempting to change the account to my personal one ended up in login failure, however after a few such attempts and opening multiple web designers in separated tabs, I correctly logged in under my personal account. After a while I could no longer replicate the issue.
I guess the issue may have been that I was logged in to Azure under both my personal account and the AD user at the same time in same browser when setting eveything up.