What is different between ApiAuthorizationDbContext and IdentityDbContext? - c#

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.

Related

Workaround for Circular Dependencies between API and ClassLibrary Projects

I have one API projects with all endpoints and once ClassLibrary which holds all Dtos(model properties). Api projects have reference to ClassLibraray(Common). Actually I want to implement IValidatableObject for my Dtos to validate against the data in DB in classLibraray. For that I need to call Servicees which are available in the API projetcs. I cant refer API to Common(ClassLibraray) projects as its causing circular dependency. I am trying to resolve CD using Interface in newly created classlibraray but no luck. Anyone who can help me here with the solutions would be great. Thank you.
I have tried making Dtos class as partial and one same partial class in API but no luck. Also I am trying to inherit that model in the API with IValidatableObject but that not helping though
PFB how I am trying using inheritance in API sulution
public class DepartmentDto : CreateDepartmentDto, IValidatableObject {
Step 1. Create an interface for your API and put it in a separate assembly.
interface IMyApi
{
void Foo();
}
class MyApi : IMyApi
{
public void Foo()
{
//etc
}
}
Step 2. Register your API with your IoC container (i.e. service provider) if you have not already done so.
Step 3. Inject your service provider into the validation context when you construct it.
var validationContext = new ValidationContext(myDto, myServiceProvider);
Step 4. Retrieve the service within the Validate method.
public class DepartmentDto : CreateDepartmentDto, IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var myApi = validationContext.GetService(typeof(IMyApi));
myApi.Foo();
//etc

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>
{
}

EF Core reusable DbContext

I'm trying to create a reusable base for future web applications made with asp net core.
I created a library that contains a BaseDbContext that inherit from IdentityDbContext:
public class BaseDbContext : IdentityDbContext<ApplicationUser>
{
public BaseDbContext(DbContextOptions options) : base(options)
{
}
}
Inside this library there are some services for login and creation of Users.
Everytime that I will be creating a new WebApplication I will reference the library and I will create a new DbContext like this:
public class ProjectDbContext : BaseDbContext
{
//some generics DBSET
public ProjectDbContext (DbContextOptions<ProjectDbContext> options) : base(options)
{
}
}
And in the startup:
services.AddDbContext<ProjectDbContext>(options =>
{
options.UseSqlServer(connection);
});
Since the service for the login and creation of users require a reference of BaseDbContext, I created a IDbContextFactory inside the base project that will be implemented by the main project like this:
public class ProjectContextFactory : IDbContextFactory
{
private readonly ProjectDbContext _projectDbContext;
public ProjectDbContextFactory(ProjectDbContext remDbContext)
{
_remDbContext = remDbContext;
}
public BaseDbContext GetBaseDbContext()
{
return _projectDbContext;
}
}
This factory will be used inside the base project to get a reference to the BaseDbContext.
Is this a good thing to do? Can this create some kind of problems?
In general, no, this is not a good thing to do.
that will contains the entities that will be used for all web applications
If there's entities that are common to all projects, then those should be factored out completely. In other words, you'd have one project (your base project) with a context like UserContext, which will have your User and Credential entities, and then every other project would have its own separate context that deals with just what it needs. If the other application(s) need to access users, they'd either do so via an instance of UserContext or, better, through a service, such as an API.
That said, it sounds like you're rolling your own auth, which you should emphatically not do. Use Identity. And, if you need to share that between applications, you need a centralized auth provider, such as Identity Server.

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

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>()

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