Entity Framework SQL Connection issues with Integrated Security - c#

On one side I have a Windows service that uses Entity Framework to connect to a SQL Server instance and work with a database there.
On the other side I have a WIX based installer which has a bootstrapper .NET based GUI in which the user can enter connection details to be used in the connection string by the service. In this installer GUI I am also performing a check on the user provided data and check the database connection (using SqlConnection.Open() and even creating/dropping a database).
The issue appears in a workgroup environment, no domain controller present, and when the user chooses Integrated Security as an option. The bootstrapper application successfully connects to the SQL server and performs some operations with it, but then the Windows service fails to connect to the SQL server using Integrated Security. If I follow up by changing that to user and password authentication, the service works correctly.
Is there any way to have the bootstrapper fail connection if the service would fail, or the other way around?
Thanks.

The most likely cause is the user the service is running under and the user the installer is running under are different.
If the User running the installer has access to SQL Server through windows authentication the connection would succeed. Then if the service runs under a different account (Say LocalSystem) the user the service is running under does not have permissions to use integrated security.
The way around this to use a service account which has permissions on the server or use SQL Authentication.
I ran into this recently when deploying a service. The only way to fail the bootstrapper connection would be to run it as the account the service will run under (impersonation is one way to accomplish this) otherwise there is no way you can test the connection correctly.
Since you mention workgroups and no domain controller there may be some pass through going on with the user names and passwords. At one place I worked, on one of the SQL boxes (off the domain) each developer had a local windows account with the same password as their domain account. This allowed a pass through authentication (due to the username and passwords matching) and access to SQL Server. That may be what is going on.

Related

Login fails with C# application / SQL Server database installed in a different machine

I created a desktop application which runs with SQL Database. In my machine installation runs perfect. When installing in other machines it do not. Message is:
Cannot open database “verticaladminmod” requested by the login. The login failed. Login failed for “Fina-PC\Fina”
My machine:
Name “MI_PC-PC”
Owner: “MI_PC-PC\MI_PC”
Database: “verticaladminmod”
Connection string:
Data Source=localhost;Initial Catalog=verticaladminmod;Integrated Security=True
Windows 7 64 bit
SQL Server 2014 Express, instance “SQL Server (MSSQLSERVER)”
Other machine installation:
Name “FINA-PC”
User Name: “Fina-PC\Fina”
Windows 7 32 bit
SQL Server 2012 Express, instance “SQL Server (MSSQLSERVER)”
Already understand it should be a matter of credentials, but after several attempts could not get to make it work. Need specific orientation with detailed steps if possible in order to configure where needed looking forward to resolve this issue and understand it in depth as well. Thank you so much!
First, the connection string needs to point at the correct machine (FINA-PC rather than localhost). In some cases you need an instance there, as well (ie FINA-PC\MSSQLSERVER), but with the default instance you can skip the instance name. This is why localhost worked in the original connection string.
Once that is fixed, we can talk about authentication. If you want integrated security to work across machines you also want to have an Active Directory domain. If you don't have an Active Directory domain, you want to switch to SQL authentication.
SQL authentication requires you to create a user ("login", in Sql Server parlance) in the database with it's own username and password you can put in the connection string. Do not use the sa account for this. You must also then be very careful with how you store the connection string, or any decompiler will show the credential and provide full access to your DB. Once you have the new login and connection string, you must also grant permissions for the account to do the operations you need within your database.

Entity Framework Connection via Task Scheduler connects as NTAuthority/Anonymous Logon

I have a Console Application (C#) that connects to a database and sends some emails. It runs fine when a user debug in Visual Studio, but when I copy this to a server and run as a Service Account domain\AcctNotWorking I get the error below. If I switch the account that runs the Scheduled Task to my domain\login it works fine. Why is the service account trying to login as NT AUTHORITY\ANONYMOUS LOGON and any ideas how to fix this? The domain\AcctNotWorking is an admin on the server and has the appropriate permissions in SQL Server.
System.Data.Entity.Core.EntityException: The underlying provider
failed on Open. ---> System.Data.SqlClient.SqlException: Cannot open
database "MyDatabaseName" requested by the login. The login failed.
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.
Connection String: add name="ApplicationEntities" connectionString="metadata=res://*/ApplicationEntities" .csdl|res://*/ApplicationEntities" .ssdl|res://*/ApplicationEntities" .msl;provider=System.Data.SqlClient;provider connection string="data source=SQL-Server-Name;initial catalog=DatabaseName;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"
Easy, Integrated Security=True means the current user will attempt to log into the sql server using their windows identity. You either have to 1) create a user for the service to run as, and configure the service to run it under this user, then give this user permissions in the database, or 2) create a sql login with a username/password and use that in your connection string.
Here's a starting point to learn about running a service under a user account
Minimum rights required to run a windows service as a domain account
and here's a starting point for creating sql server logins
https://learn.microsoft.com/en-us/sql/relational-databases/security/authentication-access/create-a-login
Although, honestly, that seems overly complex. All you need to do is login to the server using SSMS and right click on the Security folder and create a new login. It's pretty clear. Then you create a user in the database for that login (same process, but the security folder is under the database). Not too hard. Then switch Itengrated Security=True out for User Id=myUsername;
Password=myPassword;
My preference would be to create a user account on the machine that has no rights other than what it needs to run the service, then create a login & user in sql server for this account that is also locked down to the bare minimum rights required to function. Doing this correctly can be relatively complex if you've never done it before. It is, however, rewarding and will gain you valuable experience you'll use to great effect in your career.
At least, if you go with the quick and dirty sql login method, encrypt your connection string: https://msdn.microsoft.com/en-us/library/89211k9b(v=vs.110).aspx

Test transition from Windows Authentication to SQL Server authentication

I have a windows forms application which connects to an SQL Server 2008 R2 database using variously SMO, databinding, and ODBC connections.
Currently it uses entirely Windows authentication, but a client has requested that we also allow SQL Server logins.
Given the only Windows login I have, and can have, is my own, what can I do to test whether my code is actually using the SQL Server login and not simply connecting using my own Windows login?
Alternatively, what can I do to refine this question so it makes sense?
Thanks
Your question is too general but here are some steps you should take.
Create new sql login and only give necessary permissions to this user
Update all connection strings in your application. If these are not consolidated in one config file now is the good time to do this. You can even consider creating a separate class that will handle this.
Add login form to your app that will be shown at the application startup so that user can enter credentials
Best way to test this is to simply disable your windows user in SQL Server and see if application is still running.

Reaching a file in a server through C# application

I wrote an application in c# & SQLite for storing data of all employees in a company which has around 500 employees. I want to put the database & the application in a file server/shared folder (MS server). Then all employees will have a shortcut of the application in their desktops. I want to make some input fields (text box) enabled/disabled based on the permission of the user runs the application. Whats the best practice for doing that?
I want the user can read/write in the database through my application only (the application is located in the same database folder). I don't want the user to reach the database without my application. How to do that?
I don't want the user to reach the database without my application
If your application will directly access the SQLite database via a Windows file share, this is impossible. Sure, you can make it inconvenient, but it's not really possible.
The only way to achieve this really is by introducing some middleware.
This would typically be a service (WCF perhaps) that listens for connections from your client application, authenticates them, and manages all access to the underlying database. The database would be stored in a location that is visible to the server only, and not visible through a Windows share to your users.
Also, SQLite isn't exactly a great choice for a multi-user system. You can kill two birds with one stone here - switch to a DBMS (MS SQL Server Express is free, also MySQL, PostgreSQL are common free choices) that accepts client connections over a network, and build your application to connect directly to the database server (using integrated Windows authentication may also be possible like this, so you can avoid an explicit logon). In a simple scenario this may be adequate and avoid you needing to build an explicit service layer.
In a more complex scenario, it can still make sense to have a middleware layer between the application and the database - this way, you can change the database design without changing the application design and deploying to all of your client machines - instead, just change the middleware layer in one place and your application won't know the difference.
If you don't want the users to reach your database you should create a client server architecture.
You can run your service on the same machine as the file server (running as a Windows Service) and use WCF for communication between your server and your client. You access your database from your server and let your server authenticate your users and validate that they have access to the application.
You can cheat and try to "hide" database credentials inside your client application, but that is security by obscurity and any one with some programming skills or similar can find out the credentials to the database and connect directly to the database.

How to access the database Remotely through IIS?

I have used the ASP.net with C#. I want to access the SQL Server database through web server. When executing my application from development area it's working but after deploy the application to the IIS server it shows the following exception:
CREATE DATABASE permission denied in database 'master'. An attempt to
attach an auto-named database for file D:\newtest\newtest.mdf failed.
A database with the same name exists, or specified file cannot be
opened, or it is located on UNC share.
I have used the following connection string to attached with database
Data Source = .\\SQLEXPRESS;AttachDbFileName=databasepath; Integrated Security=true
How do I access the SQL Server database Remotely through IIS?
Although the answer by Sanjay is correct, it doesn't really explain why you're getting the permission denied.
Code running in ASP.NET / IIS runs as a specific user, as defied in the worker process' config. For IIS 6 [Server 2003] (and below, I think) the default was NETWORK SERVICE for IIS 7+ [Server 2008], the default behavior is to run as a special application pool user IISAPPPOOL\yourAppPoolName.
If you grant the requisite permissions on your database for the correct user account(s) -- you should be able to get around the error and still use integrated security.
As an aside, it is generally a good idea to give the most restrictive (yet still operable) set of permissions on your database. CREATE DATABASE requires a pretty high permission level (I don't remember what off the top of my head.) If you grant that to your IIS application, you run a significant risk of allowing a less than honorable user taking control of your database system and wreaking havoc on it.
Hey Create Credential with SQL server and update your config file
connectionString="Data Source=Abcl\SQLEXPRESS;Initial Catalog=master;User ID=sa;Password=pwd12" providerName="System.Data.SqlClient"
if your are using db file like mdf
Pls use like this
connectionString="AttachDbFilename='C:\Documents and Settings\nmartin\My Documents\PS_Upload\TimeTrack\src\TimeTracker\TimeTrack\App_Data\ASPNETDB.MDF';Integrated Security=True; User Instance=True"
They key is that you've used Integrated Security=True in your conneciton string.
When you run your project in your development environment, the web application usually runs as your local user account. Furthermore, your account is usually a privileged user (admin) on the local SQL instance.
On your deployment server, IIS usually runs as a local machine account (or an account provisioned for your AppPool). That account usually doesn't have any special privileges on the SQL server instace.
As debracey points out, you normally don't want to have your app's SQL privileges high enough to cause any harm (even if it's an honest mistake on your part). One common pattern to avoid tihs is to have two separate SQL accounts for your app:
A high-priviledged account for creating and modifying your database schmea (e.g. db_owner role)
A limited-privilege account for accessing your database while your app runs (e.g. db_datareader and/or db_datawriter role)

Categories