I am trying to connect to SQL Server database from a .NET Core web application,
here is the connection string I am using:
Server =.; Database = DBNAME; User Id = tb; Password = pass; Trusted_Connection = True; MultipleActiveResultSets = True;.
The previous setup generates an exception:
An error occurred using the connection to database 'DBNAME' on server '.'.
System.Data.SqlClient.SqlException (0x80131904): Error opening session for the user 'MyDomain\ServerMachineName$'.
I think it is trying to connect using another domain account that I don't even see in the list of database users under security tab, nor in the users of the server instance.
In the startup file, the related configuration is:
services.AddDbContext<MyDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyConnectionString")));
I tried adding different users with the required privileges to the SQL Server instance and to the particular DB, but none of these worked.
Questions:
Why is the system completely ignoring the connection string I am specifying?
Is there a work around to this?
What Trusted_Connection = True; means is ignore the passed in user id and password and instead use the windows credentials of the user running the program. As your program is likely running as a service the "user" it runs as is MyDomain\ServerMachineName$.
Setting trusted connection to false will have it use the userid and password provided in the connection string.
Related
The connection string in web config saves the user name and password but I don't want to save Password in web config.
I am using Entity Framework in my application. Now I am trying to use the Azure SQL database with managed identity.
I tried to use the Secure Azure SQL Database connection from App Service using a managed identity tutorial in the docs
My connection string in web config:-
add name="Context" connectionString="metadata=res:///PubsuiteModel.csdl|res:///PubsuiteModel.ssdl|res://*/PubsuiteModel.msl;provider=System.Data.SqlClient;provider connection string="server=servername.database.windows.net;database=dbname;UID=AnyString;Authentication=Active Directory Interactive;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"
When I am trying to fetch the records from the db I am getting the below error:-
Error:-The underlying provider failed on Open.
InnerException = Failed to instantiate an authentication provider with
type
'Microsoft.Azure.Services.AppAuthentication.SqlAppAuthenticationProvider,
Microsoft.Azure.Services.AppAuthentication' for
'ActiveDirectoryInteractive'.
How do I create a connection string for entity framework with azure SQL database with managed Identity?
The guide you are referring to is helpful but overly complicated. I was struggling with it myself. What you have to do is actually fairly simple (once you figure it out).
First of all your connection string should obviously be free of any kind of user and password, and should simply look like this below:
Server=tcp:<sql-server-name>.database.windows.net,1433;Initial Catalog=<sql-db-name>;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
Replace the <sql-server-name> and the <sql-db-name> with the names of the corresponding resources in Azure.
Pass a connection to EF instead of the connection string. This is needed as you need to add the access token runtime. See the code snippet below.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connection = new SqlConnection();
connection.ConnectionString = dbConnString;
var tokenProvider = new AzureServiceTokenProvider();
var resourceId = "https://database.windows.net/";
var token = tokenProvider.GetAccessTokenAsync(resourceId).ConfigureAwait(false).GetAwaiter().GetResult();
connection.AccessToken = token;
optionsBuilder.UseSqlServer(connection);
}
Don't forget to run the SQL commands for binding your managed identity and potential real life DB users to the database.
Set an AD admin user on the SQL server resource, and log in as this user.
Run the queries below and replace <azure-resource-name> when the name of the MI for your app(s). The MI name is default the app name if it is system assigned. Instead of an MI name you can use a principal user name or AAD group name such as xxx#yyy.com or "my-ad-group".
CREATE USER "<azure-resource-name>" FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER "<azure-resource-name>";
ALTER ROLE db_datawriter ADD MEMBER "<azure-resource-name>";
ALTER ROLE db_ddladmin ADD MEMBER "<azure-resource-name>";
GO
We use entity framework to read from an existing database.
This is a simplified version of our code.
using (my context context = new mycontext())
{
if(context.Database.Connection.State == System.Data.ConnectionState.Closed)
{
_logger.Info(" Opening the connection to the database");
context.Database.Connection.Open();
}
context.Configuration.LazyLoadingEnabled = false;
IQueryable<mymodel> people;
people = context.People.OrderBy(x => x.Firstname);
_lstContacts = people.ToList();
if (context.Database.Connection.State != System.Data.ConnectionState.Closed)
{
context.Database.Connection.Close();
context.Database.Connection.Dispose();
_logger.Info(" Connection to the database Closed");
}
}
It works 100% of the time, but...
On our UAT environment we can see failed connections to the Microsoft SQL server with the error:
Login failed for user "my user". Reason: Failed to open the explicitly
specified database "null". Client my IP.
For us, these are ghost connections because at the time when we see the errors in the SQL server, our code is not executed.
Initially we didn't close and open the connection explicitly, we just added it trying to control when EF open and closes the connection, but it didn't fix the issue.
Our connection string is using the following format:
<add name="MYCN" connectionString="metadata=res://*/CVs.Cvs.csdl|res://*/CVs.Cvs.ssdl|res://*/CVs.Cvs.msl;provider=System.Data.SqlClient;provider connection string="data source=myserver\;initial catalog=mydatabase;Integrated Security=;User ID=myuser;Password=XXXXXXX;MultipleActiveResultSets=True;App=EntityFramework"/>
As you can see, we are specifying the database in the connection string and our user only have access to our database, so we understand the error when EF doesn't include the database in the connection string, but we don't understand why it's trying to perform these connections.
We know the connections are coming from our application, because we are the only one using that specific user, the IP is the IP of our server, and because the logs in SQL server tell us that the application is "EntityFramewrok"
I didn't personally see the error before, but researched for you and seen that many people suffered from the same problem discussed here: https://blogs.msdn.microsoft.com/sql_protocols/2006/02/21/understanding-login-failed-error-18456-error-messages-in-sql-server-2005/
I read all the messages in the website specified, and here are the solutions offered and at least one other user confirmed that it worked. You might not use 2005 as you didn't specify your version in your question, some solutions I believe will still work for you. Try the list below.
Solution list:
1) Please check the state number of this error and search solution by the state number in addition to the message, might give your more accurate solution proposals. Most common states are listed:
All state-error descriptions you can find here: https://sqlblog.org/2011/01/14/troubleshooting-error-18456
2) Make sure the username and password are correct.
3)
Logon to SQL Server using windows authentication.
Right click in the query window that appears and select "Open Server in Object Explorer"
Go to object explorer and open the "Security" folder and then the "Logins" folder.
Double-click the "sa" user and change the password. Also, like another user mentioned above, untick the "Enforce Password Policy" in
addition to resetting the password.
4) Try to change the password and turn off the policy, and try with new password.
exec sp_password #new = ‘sqlpassword’, #loginame = ‘sa’
alter login sa
with password = ‘sqlpassword’ unlock,
check_policy = off,
check_expiration = off
5) Run your application/browser and SSMS (if you work on it) in administration mode.
6)
Open Windows Services
Configure Microsoft Single Sign-on Service to use the proper account
Open Central Administration >> Operations >> Manage settings for single sign-on
Configure properties to use the same account used for Microsoft ‘Single Sign-on Service
7) Go to Sql server configuration manager and Enable TCP/IP and named pipes
8)
go to sql server
right click on server, choose properties
click on security
on server authentication, enable SQL Server authentication
These might help:
https://www.wikitechy.com/errors-and-fixes/sql/login-failed-error-18456-severity-14-state-38-reason-failed-to-open-the-explicitly-specified-database
https://dba.stackexchange.com/questions/90445/login-failed-for-user-error-18456-severity-14-state-38
I think this is just an access issue for myuser in the UAT environment. Just make sure myuser has access in the UAT environment for UAT database and you should be good.
I am trying to connect to a SQL Server instance via a .NET Winforms client. When I use a "Trusted connection" connection string all works fine, yet when I use a standard security connection string I get an error that the login fails.
The really confusing thing is that in the database both the Windows authentication user and the SQL Server authentication user have the exact same permissions. For testing I made both part of the "sysadmin" role.
I have got to be missing something simple but I have checked username and password over and over yet it still fails. Has anyone else run into this?
This works ...
string connectionString = #"server=dbserver.myhost.com\myinstance;database=MyDB;integrated Security=SSPI;";
This does not work ...
string connectionString = #"server=dbserver.myhost.com\myinstance;database=MyDB;User Id=testuser;Password=mypassword;";
I write a win app,and i create my database on the server by codes.now every client on local network can't login to my database and this error occured
:"cannot open database "test" requested by the login.the login failed for user "farzane".
the connectionstring for to make my database is:
ConnectionString=#"Data Source=SERVER\SQLEXPRESS;Initial Catalog=master;Integrated security=SSPI;Persist Security Info=False";
and it's my connection string for open my database:
ConnectionString=#"Data Source=SERVER\SQLEXPRESS;Initial Catalog=test;Integrated security=SSPI;Persist Security Info=False";
how can give permission for logining to my database to any client with codes???
thanks in advance for any help.
I would check two things here:
Ensure that your SQL Express install allows remote connections. (Simple to check using SQL Server Studio Manager).
You are using trusted authentication in your connection string. You have to explicitly give users on your domain access on the database. You will have to this in SQL Server.
are you using a domain for the network ?
if yes then make sure that the user name has access to the SQL server
if you're using a workgroup then it won't work... just create a user on the sql server and use the sql server auth at the server and connection string
Points i concluded:
First of all the users who are going to create the database , must be authorized to use master database. So ask your admin to allow permission to farzanne.
If you(farzanne) are admin, set farzanne to create databases permission to true. Or the other users that might create dbs. Also, if you allow all users then it will be difficult to handle, your application, so be alert.
What is the need of the dynamically createing database from application. Is this a part of setup or deployment or you are creating an isolated space that is different user different database.
i am making a simple c#.net winform application with a form1, which will connect to sql server.
i want that before establishing a connection to sql server , the application asks the user to enter the login name & password to connect.
for this what should i do:
take the login name & password in two text boxes & pass them the to the connection string
or
should i pass them to the app.config file & then use the string from app.config file in the form1.cs?
will this be ok with the security issues? if not, then what are the other ways of implementing this task?
I would do this:
use a SqlConnectionStringBuilder component
define things like server name, database name etc. from your app.config
that component also has two properties for user name and password - fill those from a dialog box where you prompt the user for this information
that SqlConnectionStringBuilder then gives you the proper connection string to use for connecting to your SQL Server
Update:
My suggestion would be to store the basic connection string like this:
<configuration>
<connectionStrings>
<add name="MyConnStr"
connectionString="server=A9;database=MyDB;" />
</connectionStrings>
</configuration>
Then load this "skeleton" connection string (which is incomplete - that alone won't work!) into your SqlConnectionStringBuilder:
string myConnStr = ConfigurationManager.ConnectionStrings["MyConnStr"].ConnectionString;
SqlConnectionStringBuilder sqlcsb = new SqlConnectionStringBuilder(myConnStr);
Then grab the user name and password from the user in a dialog box and add those to the connection string builder:
sqlcsb.UserID = tbxUserName.Text.Trim();
sqlcsb.Password = tbxPassword.Text.Trim();
and then get the resulting, complete connection string from the SqlConnectionStringBuilder:
string completeConnStr = sqlcsb.ConnectionString;
using(SqlConnection _con = new SqlConnection(completeConnStr))
{
// do whatever you need to do here....
}
Pass the login to the connection string. app.Config is not a place to store user interaction.
Another way of implementing it might be to authenticate on the SQL server with Windows authentication. That way the local Windows user can have certain security privileges on the database and the user of the application would net necessarily have to enter any credentials.
What are the credentials used for? Are they used for establishing a connection with the database, or to access a user account entry and security privileges in the application?
For securing strings, use SecureString Class.
Sql authentication details is always kept seperate from application authentication details(There are exceptions...eg: ur making ur own version of sql server client)
Keep your database connection details in app.config.
It should Ideally contain one user with app level restrictions enabled.
The Login you speak about is an authentication module which exists in C#. eg: windows authentication,forms authentication etc.