I am using aspnet identity for create,update delete,login and logout new users in my asp.net WebAPI application. When i create new user its automatically storing the PasswordHash and security stamp in the database. But now my want to store Password salt string in database . I have searched a lot but unable to do it. Is it possible to save salt by using aspnet identity? If yes then how?
My current AspNetUser table
Code first
1. Create Application User class
You need to create a class that inherits from IdentityUser.
public class ApplicationUser : IdentityUser
{
public string UserSalt {get;set;}
}
2. Context
Then you need to adjust your models (let's suppose you're using EF code first).
Your application context (you can create a special class for ApplicationRole too):
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string> {...}
^ Just in case your application is an identity provider and your application context represents your identity context.
3. Adjust model
Add property to model builder:
modelBuilder.Entity("IdentityProvider.Models.ApplicationUser", b =>
{
...
b.Property<string>("UserSalt");
...
}
4. Adjust relationships
Also make sure that everywhere you had IdentityUser as entity name in your code first approach to switch it to ApplicationUser.
Related
I'm trying to realize a MVC .NET core application with Identity scaffolded.
I stared from an empty MVC app, I added some Identity scaffolded items, with a specific IdentityDbContext and a specific IdentityUser:
public class MyCustomUser : IdentityUser
{
[PersonalData]
[Column(TypeName = "nvarchar(100)")]
public string FirstName { get; set; }
}
Then I created some custom model classes in the Models folder and I would like to force the EF to include those classes in the migration evoked with
Enable-Migrations
Add-Migration "MyMigration"
Update-Database
As a result I expect to see on my DB all the tables for the authentication (AspNetRoles, AspNetUsers (with its new column "FirstName") etc) and the tables created using the classes in \Models.
How can I achieve this?
Would you suggest another way to handle identity and models using EF?
I have used MVC Identity for user login and registration purposes....but i needed to add additional database table also like this are completly unrelated with Identity database table...in my application i use code first.....i have made class for this.....but i want a single context in whole application
public DbSet<Dept> Dept{ get; set; }
public DbSet<Course> Course{ get; set; }
public DbSet<Etc> Etc{ get; set; }
As asp.net identity have ApplicationDBContext and i was using other database context which is defined by this
public class MainContext : DbContext
So what i want is i should be able to create my database table and Identity table when database changes detected and i am creating user and role when application starts at ApplicationDbInitializer which is working ok.
Now i want just a single context for whole application....
Things i have tried or think is inherit Maincontext with ApplicationDbContext
But still i can see 2 context and Other thing is i can inherit from IdentityDbContext but still there will be 2 context.
Show me simple example if possible.
Thanks.
I'm using ASP.NET MVC 5 with a Database-First workflow. I've created the Identity tables (AspNetUsers, AspNetRoles etc.) in my existing database however I'm having problems getting the register and login functionality to work properly.
This is the IdentityModels.cs class
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("MyConnectionString") // I use "MyConnectionString" instead of "DefaultConnection"
{
}
This is what the EF connection string from the web.config looks like
<connectionStrings><add name="MyConnectionString" connectionString="metadata=res://*/Entities.MyModel.csdl|res://*/Entities.MyModel.ssdl|res://*/Entities.MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=My-Pc\SQLEXPRESS;initial catalog=MyExistingDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
And for good measure here's the context class generated from the edmx
public partial class MyConnectionString : DbContext
{
public MyConnectionString()
: base("name=MyConnectionString")
{
}
To me all seems well and it should be able to create users in the database however I'm getting the following error when logging in or trying to register respectively:
For login:
The entity type ApplicationUser is not part of the model for the
current context
Line 73: var result = await SignInManager.PasswordSignInAsync(model.Email,
model.Password, model.RememberMe, shouldLockout: false);
Exception Details: System.InvalidOperationException: The entity type
ApplicationUser is not part of the model for the current context.
For register:
The entity type ApplicationUser is not part of the model for the
current context
Line 155: var result = await UserManager.CreateAsync(user,
model.Password);
Exception Details: System.InvalidOperationException: The entity type
ApplicationUser is not part of the model for the current context.
Most articles around seems to be focusing on Code-First and how to go from LocalDb to SQLExpress etc. and how to change the connection string however I haven't been able to solve this problem for a good amount of time.
Edit, solution: As #ChrFin mentioned you could use them both side by side which is what I ended up doing. I simply added a new regular connection string in web.config and let it point to the existing database. PS. remember that the connection string name cannot be the same as the existing one and must be the same you provide to the ApplicationDbContext constructor.
I THINK this scenario is not supported by ASP.NET Identity as it needs a DbContext which extends IdentityDbContext<ApplicationUser> (or similar).
Why are you forcing Identity into your DB-First context?
You can use a Code-First context for Identity alongside your other DB-First context without problems...
You can resolved this problem by following these steps:
1-create aspnetuser etc tables on your database (whatever DB you want
to use)
simply connect the application with that database not using entity framework, i'm saying just simple connection.
you will find connection string in web.config file.
place this connection string into identity model clsss
your Register and Token methods now running
now you can use entity framewoek for rest of your tables by data first approach
i am currently implementing aspnet identity(code first) for WEB FORMS(VS 2013) i would like to know how to add additional properties like date of birth to the entity.
i can currently do this via MVC but have issues on aspnet WEBFORMS.
You should create a class which inherits from IdentityUser and add your custom properties to it. An example would look like the following
public class ApplicationUser : IdentityUser
{
public DateTime DateOfBirth { get; set; }
}
The next step would be to change your database context to use this new user
public ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
...
}
If that doesn't solve your problem you should post what your issues actually are.
I'm new to MVC 5 and trying to get my head around the new Identity membership system, so forgive my newbie/ignorance on the subject.
My goal... Restrict data sent back to the user to make sure it's the user's data. I am using Entity Framework and have a set of APIs exposing data for a SPA app. On top of adding [Authorize] to the APIs, I need to (of course) also make sure the data getting retrieved is only the user's data, e.g. if I have a travel site, I only want to return that user's reservations not all in the system.
What I have done so far... I started a new MVC project so I can use the Identity membership. Next, I added my existing model and data layers that contain my model for the reservation system. Success... all working as it should. In the database, I see all of my travel site tables, a set of AspnetUser tables and a set of Identity tables. Next up, link the reservation entities to the users.
So, in my model, I create links to what I think is going to be the AspNetUsers entities/tables (as this is where both external and regular users are stored --- for me only external users, fb/google/etc, are stored in the Identity tables) in several of my classes:
public class Reservation() {
... properties ...
// Add FK to link reservation to user
[ForeignKey("User")]
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
}
... and, I'm using the standard IdentityModel.cs file...
public class ApplicationUser : IdentityUser
... but, instead, it's linking to the Identity tables. So, this does not work...
public IQueryable<Reservation> Reservations()
{
var sUserId = getUserId(); // fctn below
_repository.Reservations.Where(r => r.UserId == sUserId);
}
This foreign key is linked to the IdentityUser table, not the AspnetUser table. If the user is a locally registered user, not one using an external login (fb/google/etc), the system only adds the user in the AspnetUser table, not the IdentityUser table. This means I can't just add the user's Id to the data table because the foreign key isn't valid as the user's Id isn't in the IdentityUser table. I quickly added this function for testing in my API controller for testing:
private string getUserId() {
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
if (User.Identity.GetUserId() != null)
{
return User.Identity.GetUserId();
}
else
{
return "";
}
}
So, my question is what should I be doing here to achieve my desired result of associating data to users? Should the foreign key/table be to something different? Am I taking an incorrect approach in adding foreign key relationships back to the user tables?