why contained database user needs Persist Security Info=True - c#

I have a database where I created a contained user and I needed to connect to my web app using that user. I have always been able to connect to the web app with a standard user having Persist Security Info=False.
However, the only way I was able to connect with the contained user was changing my connection string to Persist Security Info=True, otherwise I'd get a login failed sql exception even though I was able to connect using SSMS. I'm not sure why it worked, does anybody know why a contained user needs the property set to True?

For you web app, are you using Entity Framework ?
And for your DbContext are you using IdentityDbContext ?
If so, I had the same problem. I was able to connect directly with SqlConnection but encountered an "Access Deny" error when connecting with Entity Framework.
When I gave enough permissions to my user, all queries were very slow.
When instantiating the Context (with IdentityDbContext) you should set the second parameter to false.
public AdeleDbContext(string connectionString) : base(connectionString, false)
{
}
The second parameter is throwIfV1Schema and when set to true (which is the default value), it will validate schema against the database by calling SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=#Table for many columns.
That was the reason why the connection was slow and user needed more permissions when connecting to DB with Entity Framework and IdentityDbContext.

Related

Fail to open the database

Well, i know this question was asked many times on this platform. Nothing seems to work for me. I looked at this Cannot open database "test" requested by the login. The login failed. Login failed for user 'xyz\ASPNET'. I fully understand that.
The case is the database was created by default when i created the application. I choose the Individual Authentication. I then expand the database using the Entity Framework 6. I want to create a CRUD operation through the Entity Framework 6 by generating .edmx file. The error occurs when I tried to attach the database to the program.
I tried opening it with MSSQL Server to assign right to the user. After it will complain the file is corrupt. If anyone will help me to open it or how to generate a CRUD on that. I will be thankful.
You can see your connection string something like below
Data Source=.\SQLExpress;Initial Catalog=something;Integrated Security=True
Remove Integrated Security=True from your connection string then it will work
Update
it is recommended to keep Integrated Security . When false, User ID and Password are specified in the connection. When true, the current Windows account credentials are used for authentication.Possible states are true, false, yes, no, and sspi Read More

C# switch from local db to external (Azure) db causes errors

I have used the built in Database that comes with Visual studio by using Code First with Entity Framework. Now I wanted to move to an external database so I created one and saved the connections string. So I connected to my azure database by supplying the connection string in the db context constructor. Now though, the problem is that Entity Framework isn't able to create the necessary tables. When I run my application and try to access something, I get System.Data.SqlClient.SqlException: 'Either the parameter #objname is ambiguous or the claimed #objtype (COLUMN) is wrong.'
And I assume this is beacuse my azure db is empty. Why doesn't Entity Framework create the tables?
The error was that I had forgotten to run migration on the new database:
*Add-Migration newDb
*Update-Database

Error: the underlying provider failed on open. system.data.sqlclient.sqlexception login failed for user

After deploying my C# win app in client computer, the following error occurs:
The underlying provider failed on open.system.data.sqlclient.sqlexception
login failed for user. cannot open database "EmdadKhordo" Requested by the login
This is my connection string:
metadata=res://*/Models.EmdadKhodroDB.csdl|res://*/Models.EmdadKhodroDB.ssdl|res://*/Models.EmdadKhodroDB.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=EmdadKhodroDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
I use Entity Framework to access a SQL Server database.
Based on the cannot access database error message, authentication succeeded to the SQL instance but the specified database cannot be accessed. This may be because the EmdadKhodroDB database does not exist, is not online, or (most likely) inaccessible under the current security context. Make sure the account you are using has access to the database and the needed object permissions.
The DCL below will add the user to the database. You will also need to grant object level permissions directly to the user or a role of which the user belongs.
USE EmdadKhodroDB;
CREATE USER [YourDomain\YourAccount];
You can also manage your Windows user rights using SQL Management Studio. Just follow instructions from here for creating a new login and also configure mappings to each database you need access to.
Basically you need to make sure that your login is properly defined (Security -> Logins) and that it has the appropriate rights on EmdadKhordo database (read, write etc.). The recommendation is to allow the minimum required rights (e.g. do not allow to alter tables, if only SELECT, INSERT, UPDATE, DELETE statements are performed by the user).

C# creating a database programmatically with SMO

I am trying to create a database, but once created, I cannot connect to it.
The server is Microsoft SQL Server 2008 and using .Net 4.5. We're creating the database with SMO, but we're usually using Dapper to connect and query the database.
This is the code I have so far, which works :
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connectionString);
Microsoft.SqlServer.Management.Smo.Server srv = new Microsoft.SqlServer.Management.Smo.Server(new Microsoft.SqlServer.Management.Common.ServerConnection(con));
var database = new Microsoft.SqlServer.Management.Smo.Database(srv, dbName);
database.Create(false);
database.Roles["db_datareader"].AddMember(???);
database.Roles["db_datawriter"].AddMember(???);
database.Roles["db_backupoperator"].AddMember(???);
srv.Refresh();
Noce the ??? ? I have tried
System.Environment.UserDomainName + "\\" + System.Environment.UserName
and
System.Environment.UserName
but it fails (update) with the error Add member failed for DatabaseRole 'db_datareader'. with both values.
The problem is that when I create the database, I cannot coonect to it for some reason (using Dapper), from the same program. (update) I get the error message : Cannot open database \"<database_name>\" requested by the login. The login failed.\r\nLogin failed for user '<domain>\\<username>' (where <database_name> is the database name, <domain> my logon domain, and <username> my Windows logon).
Am I missing something? Am I doing th right thing? I've tried searching the web, but it seems no one creates database this way. The methods are there, it should work, no?
** Update **
If I comment the database.Roles["..."].AddMember(...) lines, and I add a break point at srv.Refresh(), resuming the program from there solves everything.
Why a break point solves everything? I can't just break the program in production... nor break the program when creating the database everytime.
It sounds like the Dapper connection issue is a problem with SQL Server doing some of the SMO operations asynchronously. In all likelihood, the new Database is not ready for other users/connections immediately, but requires some small time for SQL Server to prepare it. In "human-time" (in SSMS, or a Breakpoint) this isn't noticeable, but "program-time" it too fast, so you probably need to give it a pause.
This may also be the problem with the Role's AddMember, but there a a number of things that could be wrong here, and we do not have enough information to tell. (specifically, does AddMember work later on? and are the strings being passed correct or not?)
This is happening because you've created the user, but no login for that user. Though I don't know the exact syntax, you're going to have to create a Login. You'll want to set its LoginType to LoginType.WindowsUser. Further, you'll likely need to set the WindowsLoginAccessType to WindowsLoginAccessType.Grant and you'll need to set the Credential by building one, probably a NetworkCredential with the user name you want.
To put a visual on this, the Login is under the Security node for the Server in Management Studio whereas the User is under the Security node for the Database. Both need to exist for access to the SQL Server.

Why does the "drop user" command for SQL not work in C#?

Why does the drop user a_2 command not work when I try to use it in C#, while when I tried it in SQL Server Management Studio, it works there !!???
This is the code that I used it when I create the user & give it a permission:
use DataBaseName;
create login a_2 with password='Aa123';
create user a_2 for login a_2;
grant insert to a_2;
..........
The connection string used :
Data Source=TheServerName;Integrated Security=True;database=master
Note:
I tried to drop a database from C# and it works perfectly without any problem, but when I use it to drop a user the problem raised here !!!
This is the exception that gets raised
Exception is: Cannot drop the user
'a_2', because it does not exist or
you do not have permission.
I believe your problem is that "you do not have permission". Your application is running as a different user from you. You can solve this by either giving the default application user the necessary permissions on the database (not a good idea) or by creating a special user in the database for your application and having the application run as that user.
Be aware that giving your application (or any user, for that matter) permissions to drop users could be very risky if someone figures out how to hack your application. And you aren't actually including the ability to drop the database in your app, are you? Think about it. Instead of creating users in the database, consider creating a Users table just for your application. Then your users won't have such extensive rights to your actual database.
DROP USER would require use DataBaseName;
Or a different connection string
Data Source=TheServerName;Integrated Security=True;database=DataBaseName
That is, the DROP USER only makes sense in the context of your database. When you run it later you are in the context of master = fail.

Categories

Resources