Customizing IdentityUser from dotnet new webapp --auth Individual -o - c#

I'm learning about C# and dotnet core, I am currently working on the template
dotnet new webapp --auth Individual -o WebApp1
However, it does a lot of things for me behind the scenes that I don't understand.
I'm rummaging through the code to find how the login view is created and handled, but have had no such luck.
Currently, I am attempting to add a column to the database given in this template, shown I think here:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();

The dotnet core team decided to abstract their default UI for authentication in a Razor Library, look for a Dependency -> SDK -> Microsoft.AspNetCore.App -> Microsoft.AspNetCore.Identity.UI
Look at the code for this package here
This should give you an idea of what is actually going on int the background.
As for extending the User model
public class CustomUser : IdentityUser
{
//custom properties
}
Then you want to configure Identity middle ware to recognise this as the main model for your users.
services.AddDefaultIdentity<CustomUser>();
Don't forget to update your database inheritance so the correct table is created.
public class ApplicationDbContext : IdentityDbContext<CustomUser>
{
...
}

IdentityUser is the base "user" class for Identity, so it's filling that in so no additional effort is required on your part. That's fine if you don't want to customize the user, but since you obviously do, simply just create your own class that derives from IdentityUser:
public class MyUser : IdentityUser
{
public string Foo { get; set; }
}
Then, use your custom user class as the type param in place of IdentityUser:
services.AddDefaultIdentity<MyUser>()

Related

What is different between ApiAuthorizationDbContext and IdentityDbContext?

What is different between ApiAuthorizationDbContext<TUser> and IdentityDbContext<TUser> in a Web API project?
DbContext can inherit those but don't know what is different between those
(I'm using .NET 6.0 and Entity Framework Core for Web API project)
Except for what #gbede said about the ApiAuthorizationDbContext<TUser> usage, ApiAuthorizationDbContext<TUser> force TUser to extends IdentityUser instead of IdentityUser<TKey>. This means it is impossible to use Identity Server on application with ApplicationUser : IdentityUser<Guid>(or anything different from IdentityUser<string>).
IdentityDbContext can work with different IdentityUser<TKey>, you can customize your model like:
public class AppUser:IdentityUser<Guid>
{
//add any additional properties
}
Then use the DbContext like:
public class MvcProjContext : IdentityDbContext<AppUser,IdentityRole<Guid>,Guid>
{
public MvcProjContext (DbContextOptions<MvcProjContext> options)
: base(options)
{
}
}
As you can see in the source code, or in the documentation, ApiAuthorizationDbContext inherits from
IdentityDbContext and it also implements IPersistedGrantDbContext which
is responsible for storing consent, authorization codes, refresh tokens, and reference tokens.

Asp.net core role based access identity / roles make user table self referencing

Hi I am trying to model an access control system where access is granted by role to certain actions. im trying to use asp.net core with identity and roles. it seems the default identity comes with its own tables for users. The users table i have need to be self referencing as a users will have managers who are also users.
is it possible to make the default table that comes with identity do that?
If you want to add additional properties to the already existing IdentityUser, all you have to do is inherit the IdentityUser class and then add your own properties then you go to the startup file and your dbcontext and do the following
public class InheritedUser : IdentityUser
{
public bool HasTwoHeads { get; set;}
}
your startup
services.AddDefaultIdentity<InheritedUser>()
.AddEntityFrameworkStores<CustomDbContext>() .AddDefaultTokenProviders()
.AddDefaultUI(Microsoft.AspNetCore.Identity.UI.UIFramework.Bootstrap4);
Then your Inherited DbContext
public class InheritedDbContext : IdentityDbContex<InheritedUser>
{
}

ASP NET CORE Can't scaffold Identity using existing DbContext - how do I specify options when scaffolding?

Steps to recreate:
1) create new asp net core mvc project.
2) create a new model and scaffold an API controller with read/write
3) delete bootstrap.css
4) change the created DbContext to inherit from IdentityDbContext
5) try to scaffold an identity
6) get error
I've scaffolded a set of objects from a data object which has given me:
namespace WebApplication1.Models
{
public class AllTheOtherStuffDbContext : DbContext
{
public AllTheOtherStuffDbContext() : base("name=AllTheOtherStuffDbContext")
{ }
public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies { get; set; }
}
}
Now I'm trying to scaffold an identity set for my db but using the same context, so I change DbContext to IdentityDbContext<IdentityUser> as per some different answers I've found, but when scaffolding and generating code, I get this message:
Cannot use an existing DbContext with the '--useDefaultUI' option.
I looked up UseDefaultUI...
and in a separate project I see by scaffolding an Identity I get this line added to my startup.cs:
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
I presume the problem now is because I got rid of Bootstrap in my current project (because I hate it) so I want to STOP the scaffolding from trying to add that DefaultUI line - how can I do this while using visual studio? Can I specify a command line instead of using the menu option to add scaffolding?
So you have used IdentityDbContext<IdentityUser>
public class AllTheOtherStuffDbContext : IdentityDbContext<IdentityUser>
{
...
}
You will have to use this DbContext here: .AddEntityFrameworkStores<AllTheOtherStuffDbContext>();
To stop the ui scaffolding use services.AddIdentity<TUser, TRole>()
P.S. I dislike the bootstrap template too.
Create the project with the default Identity and then Scaffold Identity. This should work fine.

How to change the type of the user's id from string to int in Asp.NET Core 2.2?

I have an application written using C# on the top on Asp.Net Core 2.2. The application was written on the top of Core 2.1 but then upgraded to Asp.net Core 2.2.
Now, I decided to change the Id type of the User model from string to an integer.
To override the string/default type, I created a User class like so
public class User : IdentityUser<int>
{
}
Then I created a Role class like so
public class Role : IdentityRole<int>
{
}
Finally, I updated the ApplicationDbContext class like so
public class ApplicationDbContext : IdentityDbContext<User, Role, int>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Then I deleted all the database tables that start with AspNet and the _Migrations table.
Now, every time I run my app I get the following error
InvalidOperationException: No service for type
'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]'
has been registered.
Here is my Startup.cs class
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<User>().AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication()
.AddFacebook(facebookOptions =>
{
facebookOptions.AppId = Configuration["Authentication:Facebook:AppId"];
facebookOptions.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
I also tried to so the following code in my Startsup file
services.AddScoped<UserManager<User>>();
Here is a screenshot of the stack trace
The call to AddDefaultIdentity<TUser>() registers UserManager<TUser> with the Dependency Injection container. Before you created your own custom TUser type, you would have been using IdentityUser here, which would have registered UserManager<IdentityUser>.
With the change from using IdentityUser to using User, you now register UserManager<User> instead of UserManager<IdentityUser>. The error message from your question shows that a partial view within your project is attempting to receive an instance of UserManager<IdentityUser> from the DI container, but it should be requesting an instance of UserManager<User> due to your change. That means the following change would be needed in the partial view:
#inject UserManager<IdentityUser> UserManager
-becomes-
#inject UserManager<User> UserManager
This will fix the specific error you've shown, but you'll also need to scan through the rest of the project to see if there are any other references to UserManager<IdentityUser> that also need to be changed.
You need to Add Migration and Update Database for creating schemas:
Define or update a data model in code. done
Add a Migration to translate this model into changes that can be applied to the database.
Check that the Migration correctly represents your intentions.
Apply the Migration to update the database to be in sync with the model.
Repeat steps 1 through 4 to further refine the model and keep the database in sync.
For Creating Migrations
dotnet ef migrations add InitialCreate
or
Add-Migration InitialCreate
For Updating Database
dotnet ef database update
or
Update-Database
You can get further details about schema customization and migration from Identity model customization in ASP.NET Core
Did you update your db?
If this done, then just change this
services.AddDefaultIdentity<User>().AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
To
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
And this is unnecessary.
services.AddScoped<UserManager<User>>();
Just remove it.

Change Id type of asp.net core 2.2 IdentityUser

I'm new to dot-net core 2.x, so...
I would like to change the type of the Id in asp.net core 2.2 IdentityUser from string to int.
All the examples I've found via google (and the stackoverflow search facility) are giving me examples of asp.net core 2.0 which provides an ApplicationUser when you scaffold Identity (which 2.2 did not provide).
SO, I'm at a loss.. The first thing I tried (which I had high hopes for) was:
services.AddDefaultIdentity<IdentityUser<int>>()
.AddRoles<IdentityRole>()
.AddDefaultTokenProviders()
.AddEntityFrameworkStores<ApplicationDbContext>();
But, I get the following error when I try to Add-Migration InitialCreate -Context ApplicationDbContext:
An error occurred while accessing the IWebHost on class 'Program'. Continuing without the application service provider. Error: GenericArguments[0], 'Microsoft.AspNetCore.Identity.IdentityUser`1[System.Int32]', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type 'TUser'
Thoughts? Ideas? Documentation I can read?
For changing IdentityUser key type from string to int, you also need to change the IdentityDbContext to IdentityDbContext<IdentityUser<int>,IdentityRole<int>,int>.
Startup.cs
services.AddDefaultIdentity<IdentityUser<int>>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
ApplicationDbContext
public class ApplicationDbContext : IdentityDbContext<IdentityUser<int>,IdentityRole<int>,int>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Remove Migrations folder and delete the existing database
Run command to add and update the database
You can write your own implementation that derives from IdentityUser
public class AppUser : IdentityUser<int>
{
}
Then register it:
services.AddDefaultIdentity<AppUser>()
This is also useful if you want to add additional properties to your user model.
Remember that because you are changing primary key of the tables, so you will need to recreate these tables instead of updating them.

Categories

Resources