Cannot Create Database with credentials using Entity Framework Code-First? - c#

I'm a bit new to code-first approach but I used Database first approach before using entity framework, now I want to work with code first instead and its kinda a habit.
I started creating models and its all good, then enabled migrations and add-migration as well and all works well, but when I run Update-Database command I get an error.
Hence I want to create a database with code-first using credentials, after a lot of research I didn't find a solution and mostly tutorials use "Trusted Connection".
What I use
App.Config
<connectionStrings>
<add name="CodeFirst" connectionString="Server=.\SQLEXPRESS;Database=CodeFirst;User ID=anyuser;Password=anypassword;"
providerName="System.Data.SqlClient" />
</connectionStrings>
DbContext Class
public class CodeFirstContext : DbContext
{
public CodeFirstContext() : base("name=CodeFirst")
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
}
The Error I get
Login failed for user 'anyuser'.
The question is I did something wrong ? or using credentials can't be done using code-first approach ?
Thanks in advance

OP:
I want to create a database with code-first using credentials,
...and:
after a lot of research I didn't find a solution and mostly tutorials use "Trusted Connection".
Therein lies the problem with code-first approaches when deploying to a new database using a specific login - it's a chicken and egg because:
the database doesn't yet exist
the connection string is requesting an explicit login
the login does not yet exist in say SQL
because the database doesn't exist
OP's config:
<connectionStrings>
<add name="CodeFirst"
connectionString="Server=.\SQLEXPRESS;Database=CodeFirst;User ID=anyuser;Password=anypassword;"
... />
</connectionStrings>
So what's the solution?
Use Integrated Security: this allows you to create the database from scratch from code. However any other logins you may need might have to be created later. However, DB-speaking, it's a bit of a bad practice because you should get into the habbit of having one account for deployment (with just enough rights for deployment) and another for general app access (and no rights for deployment)
Create Login First: this allows you to use your specified login however you most likely will need to create a blank database first from SQL before you can create the login. Code-first purists may not like this idea.
The latter does follow DACPAC best practices you should already be familiar with from your time in database-first. Just like how a DACPAC shouldn't be deploying logins and adjusting security neither should code-first. Afterall at the end of the day, databases don't care about whether you use code-first or database-first (under the hood, both probably employ some form of encasulated scripting) but your DB Admin might raise an eyebrow depending on how security is being used.
Are database-first approaches better?
In the theme of don't do that, try this instead, code-first tries to do everything via code and whilst a noble pursuit perhaps isn't realistic. Some things like attempting to create logins perhaps isn't possible as mentioned above.
Meanwhile database-first schema changes are carried out by deploying DACPACs from the database side. Authentication is via the login used to get into SSMS (for example) in the first place. DACPAC deployment doesn't require code, .NET or otherwise.
DACPACs can create and/modify database security including logins but is generally frowned upon.
You might want to re-think code-first. Code-first and EF Migrations hasn't really succeeded as a concept in the real world where you have staged CD environments such as DEV; TEST; UAT and PROD.
I see so many developers using code-first only for deploying to their local database. Once there, they use different means to deploy the changes to other computers including TEST and PROD whether it's TSQL scripts or database backup.
It just seems to be so much effort for something that doesn't even complete the race.

Related

Approach of setting up multi-tenant environment with ASP .NET Core

I have been struggling with the way I should set up my multi-tenant environment. In a previous project I had set it al up as a monolith where there was a tenant entity to bind al the correct data to each other. This way is quite easy to set up but the data of all tenants is in one big database.
My idea now is to set it all up in a different way. I will be using Postgres because of the possibility to also have 'schema'. My idea is to have overall data in the public schema and tenant specific data in the tenants own schema.
There are some struggles that I face where I just can not get my head around. In the picture below, you see a quick sketch of the two scenarios. The bottom one has everything in the public schema where the above one has for example domain and user in the public schema.
My idea with this is that when a customer goes to a tenants specific URL the application does not have to crawl through all possible schemas. Same counts for user. When a user wants to login to the application we also do not want to crawl through all schema's. But how do I set this up in a proper way?
Also when the user manages his domains (add/edit/delete), he is actually managing them on the public schema. Or should I avoid using public at all? I thought of putting them here because otherwise when a user enters a new domain I have to check them also on other tenants schema.
Also can I just simple set the schema name of the tenant in the domain or should this be a connectionstring?
I also read here and there about multi-tenancy but I'm unsure how the application can get the data of a tenant with the use of a different schema (public) to fetch the correct data from the tenants schema.
Should I use Inversion of Control to get a specific implementation depending on calling for Domain (public schema) or customer (tenant specific)?
https://nebulab.it/blog/how-to-switch-solidus-ecommerce-to-multi-tenant/
https://michael-mckenna.com/multi-tenant-asp-dot-net-core-application-tenant-resolution
Which Multi-tenant approach is recommended
I personally do something like your first approach + multidatabase using a first database that tells me where each tenant is located. I call it routing database.
That dB has 2 tables.
databases (if, connection string)
tenants (tenant info, database if)
This way I have the data across multiple databases and still multiple tenants per database.
Also the database id => connection string is cached usually with redis so no need to hit the dB on every request (you can even use in memory for this) with cachemanagercore library.
If a tenant requires its own database not shared is easy to handle too.
Usually a cookie with the dB id picked up on a Middleware and acceded then by a DatabaseResolver class injected where you need to access the dB with a method like DbContext Getdatabse () is all you need

Entity Framework code-first filter data on database and read it from EF

I have a C# project with EF code-first approach. The purpose is to do crud operations. My web app will be hosted under IIS under two folders
web app
WCF service
The application will pass user credentials to the WCF service and then to SQL Server database. Code first approach works well in this case.
READ scenario: the data needs to be filtered on the database level, not on application level. So I cannot directly call tables while querying SQL using EF. User will not have read access on the tables but only on views. The SQL views will have responsibility to filter the data and then pass to the service.
The question is how to proceed with EF code first approach in a way that I can leverage the benefits of EF migration s and then map the tables to the SQL views. Can anyone explain how to proceed with this read scenarios and best approach?
Entity Framework doesn't support mapping to Sql views but you can do the following:
Create an entity class that mapping your (sql) view structure.
Add a new empty migration using the add-migration -IgnoreChanges command since you don't want your entities to map to tables.
In this migration you can create (Up method) your Sql view.
It is important to note that you have to indicate the Sql view name in your entity ("view entity?") configuration (mapping) class:
public class FooConfiguration : EntityTypeConfiguration<Foo>
{
public FooConfiguration()
{
ToTable("ViewName");
HasKey(p => p.Id); // You also have to configure a key
}
}
This article from Julie Lerman could be interesting for you: https://msdn.microsoft.com/en-us/magazine/dn519921.aspx

Storing SQL credentials correctly

First off, this is an educational question - not something I am implementing in a productional application since I am learning the basics of C#.
Currently I have a solution containing 2 (actually 3, but one is unit testing) projects;
Form
Class Library
Inside the Class Library I have a class called Database.cs and it communicates with a MySQL database. I don't directly communicate with this Database.cs class, but other classes inside the Class Library do (for example Products.cs).
Though, I need credentials to connect to this MySQL database and I am not sure which way to go to do it safely.
Storing it inside the Class Library / hard-coding the credentials inside the class.
This wouldn't make sense to me since a user can easily grab the DLL and he technically got the credentials to the database.
Pass the credentials through the form to a class (like Products.cs) and that class passes it on while initializing the Database object
Could work, tried and it works but I am not sure if this is the 'neatest' way to do it.
Write a static class that contains properties with the credentials
Again, if I create this static class inside the Class Library I am pretty much off the same as my first example. If I would create this static class inside the Form, I require to add a reference to the Form-project from my Class Library (not the way I want it to be).
I tried looking stuff up but I am apparently not doing it right. Is there any other way to do this?
First of all never hard-code credentials into code because credentials tend to change over time so that means you will have to recompile and redeploy your application each time SQL credentials change.
Usually all information needed to connect to database is stored in application configuration file in a form of connection string.
If your application is web application then you're good to go because web.config (a web application configuration file) is stored on a web server and is never served to web requests.
But if your application is windows forms application, then security considerations kick in meaning that any user who uses your app could peek into application configuration file and get credentials. If it would be Microsoft SQL I would advise to use Windows Authentication. But with MySQL I guess you're doomed to store user name and password into connection string. Then I would suggest securing your connection string by encrypting it.
Also if your users can/have to authenticate against MySQL server (enter MySQL username and password), then you could use a connection string template and substitute certain parts of it with user name and password:
app.config
<connectionStrings>
<add name="MyApplication" connectionString="Location=myServerAddress;Data Source=myDataBase;User ID={0};Password={1};
Port=3306;Extended Properties=""""; />
</connectionStrings>
C# code
var username = textboxUsername.Text;
var password = textboxPassword.Text;
var connectionString = string.Format(ConfigurationManager.ConnectionStrings["MyApplication"].ConnectionString, username, password)
// at this point you have a connection string whitch could be passed to your Products class
Do not hardcode your credentials as that may prove to cause issues, firstly if you need to change your login credentials to the database at a later stage then you will have to recompile your class library, secondly as you mention the security will be compromised.
It is a good technique to leave the connection information to the main application instead of storing them in your data layer. Refactor your data layer to accept the connection string during runtime, this value needs to be passed by the main application to the data access layer.
This way you get 2 advantages:
When you deploy your application, the deployed location can have a different connection credential than your development environment
You can encrypt connection strings in your configuration file so as to increase security

C# ASP.net MVC database questions

I am trying to develop a website with C# ASP.net MVC. It's my first time using Visual Studio, C# and ASP.net so I have lots to learn but so far so good.
So far... I started a C# ASP.net MVC project and added a database by going to the Database Explorer and clicking "add connection". I then did some standard CRUD controllers and views.
I am at the stage where I want to implement User authentication. I'm a bit confused here. I am trying to make a custom Membership Provider. So I added it to my web.config file with the correct connection string etc.
When I run the project and go to register I get an error. "Could not find stored procedure 'dbo.aspnet_CheckSchemaVersion'."
From searching, I see lots of people have this problem and they always reference their hosting. People say this (http://weblogs.asp.net/scottgu/archive/2005/08/25/423703.aspx) is their solution but when I try pick a database I get an error. Not even sure of my server name.
So at this point I am wondering, did I set up the database right?
EDIT
Adding in a few pics to show exactly what I am doing. This is the aspnet_regsql.exe:
This is the provider with connection string, taken from an example on one of the links given.
This is my customized provider with connection string pointing to the last image.
This is a screen cap when I run the project and go to the default project Account register action:
and finally, this is the error screen when I submit
EDIT
Another update..
I sorted something out but I am not sure if it is correct. I am now getting an error when the page loads: "Invalid object name 'dbo.Tag'"
In order to solve this problem the only thing you need to do is create an application services DB. You can achieve this by running the following command from your Visual Studio Command Prompt
aspnet_regsql
Anyways it seems that your "custom provider" isn't using a custom structure for your DB, which might be the reason why you weren't expecting this error.
If you are using the default implementation, you can access to the user administration using ASP .NET Configuration, located on your project menu in visual studio.
The default implementation uses the following conn string keyword
LocalSqlServer
The are many ways of implementing the membership provider. My guess is that probably this conn string is not pointing to your aspnet services db, you could do something like this to specify a custom location for this db
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\aspnetdb.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" />
I made a blog post regarding this topic: How to use MembershipRole Provider and when to use custom implementations
It's hard to figure out anything from your post.
but when I try pick a database I get
an error.
You can check your server name in Surface area configuration or Sql Server Configuration Manager. If you installed Visual Studio it's probably YOUR_MACHINE_NAME\SQLEXPRESS. You can connect to it using Windows Authentication. You could also write localhost,1433 instead, but that would require enabling TCP/IP first(it's disabled by default) and setting the port number first(which in most cases is already set).

Database of registered users in ASP.NET MVC

Simple question. I know that in the default MVC application in Visual Studio, you can register a user. So I want to be able to put that info in a database and use ADO.net or LINQ to SQL to be able to communicate. How do I do this?
Do you have a database or do you want to create a new one?
If you have one just create a connection in server exploer, add new Model in Visual studio, select LinqToSql Classes, select tables from your connection and drag and drop the tables you need to the design surface. Then you can access your model from your controller where the user data is posted to.
Check this thread for example of saving.
If you don't have a database you obviously have to design and create it first
Some might argue, but you probably do not want to use the built-in membership provider. The reason is that it generates its own default schema which is good to start with, but it's better to just bite the bullet and design your own. That way, you're in control of your application, and do not have to migrate your database whenever some change is required.
The sample stuff in ASP.NET MVC uses the built-in membership and forms authentication in ASP.NET. In the Web.config, you can configure it to store the data in SQL Server rather than the default which I think might is SQLExpress. MSDN has an article on how to do this:
How To: Use Forms Authentication with SQL Server in ASP.NET 2.0
You basically just run a sql script and it generates a bunch of tables and stored procedures in whatever database you are already using. You can then access the database directly or through the membership API.
Alternatively, you can roll your own implentation of IMembershipService which just has a few methods to handle:
public interface IMembershipService
{
int MinPasswordLength { get; }
bool ValidateUser(string userName, string password);
MembershipCreateStatus CreateUser(string userName, ...);
bool ChangePassword(string userName, ...);
}

Categories

Resources