In ASP.NET MVC 5, in a controller, I have take the user that has make the request with:
ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());
With the ApplicationUser instance, how can i get all the Roles of the user?
You can get user and assigned roles by using UserManager.
var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
and then you can get your user like you already did, and also you can get roles for particular user by calling GetRoles method
userManager.GetRoles(userId);
List<string> roles = new UserManager().GetRoles(userIdString)).ToList();
below needed classes were created automatically in ASP.NET 4.5 project using VS 2015 using . the file name is IdentityModels.cs.
default 4 Nuget packages are installed including Microsoft.AspNet.WebApi v5.2.3
public class UserManager : UserManager<ApplicationUser>
{
public UserManager()
: base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
{
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
public class ApplicationUser : IdentityUser
{
}
Related
I'm placing an [Authorize(Users = "user#sample.com")] attribute at the top of my Controller:
[Authorize(Users = #"user#sample.com")]
public class PostsController : ApiController
{
... methods...
}
The user's usernames are the email address. When I sign in with user#sample.com I still get a 401 Unauthorized this controller's methods.
I've also notice that, even after the user signs in both System.Web.HttpContext.Current.User.Identity.Name and System.Security.Claims.ClaimsPrincipal.Current.Identity.Name are null.
These are a few related classes:
ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
public string Hometown { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
return userIdentity;
}
}
ApplicationDbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("MyProjectEntitiesIdentity", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
The issue happens on my local dev instance as well as on the hosted site.
I know this is very vague, I just don't know what other issues may be relevant here. So, please ask for more information and I will update the post.
I have implemented Custom Asp.Net Identity. For the sake of using my own Database Models instead of already built in ones. For It I have custom implemented all the following classes/Interfaces.
AuthUser : IPrincipal, IUser<string>
ApplicationSignInManager : SignInManager<AuthUserMVC, string>
AuthUserManager : UserManager<AuthUserMVC>
AuthUserStore : IUserStore<AuthUserMVC>
With It im using NInject to inject required dependencies in my AccountController. Constructor signature of AccountController is
public AccountController(
UsersRepository usersRepository,
AuthUserManager authUserManager,
AuthUserStore authUserStore,
ApplicationSignInManager signInManager)
{
this.UsersRepository = usersRepository;
this.SignInManager = signInManager;
this.UserManager = authUserManager;
this.UserStore = authUserStore;
}
This the NInject Code for DI
kernel.Bind<IUserStore<AuthUserMVC>>().To<AuthUserStore>().InRequestScope();
kernel.Bind<IAuthenticationManager>().ToMethod((c)=>HttpContext.Current.GetOwinContext().Authentication);
While Getting Account/Login - Normal Process of Out of the Box Identity
I Dont See any External Login Providers Listed. Thats because Inside the _ExternalLoginsListPartial.cshtml
Context.GetOwinContext()
.Authentication
.GetExternalAuthenticationTypes()
is Returning 0 Providers. Which it Shouldn't do
My Custom implemented Code
public class ApplicationSignInManager : SignInManager<AuthUserMVC, string>
{
public ApplicationSignInManager(
AuthUserManager userManager,
IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(AuthUserMVC user)
{
return Task.FromResult(user.GetIdentity());
}
public static ApplicationSignInManager Create(
IdentityFactoryOptions<ApplicationSignInManager> options,
IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<AuthUserManager>(), context.Authentication);
}
}
public class AuthUserManager : UserManager<AuthUserMVC>
{
public AuthUserManager(IUserStore<AuthUserMVC> store) : base(store)
{
}
public override Task<IdentityResult> AddClaimAsync(string userId, Claim claim)
{
return base.AddClaimAsync(userId, claim);
}
}
What am I doing wrong?
As you are probably aware, when you implement a custom AspNetIdentity provider you have to do a number of things. One of them is to implement AuthenticationOptions. If you decompile the code for the GetExternalAuthenticationTypes method you will see that part of the things it checks is that your custom AuthenticationOptions implementation has a property called "Caption". If it doesn't then it won't be returned by GetExternalAuthenticationTypes.
I created a new MVC5 project with Identity and it makes its own db which i want to change with same one but mine and on cloud server. so i have 2 connection stings and the only things that i changed was table names ex: aspnetUser to CJUser and so on. I want some simple way of changing auto generated local db to my own cloud one.
2 connection strings i have are
default one which Identity creates and
my own db which i connected.
So project works with its own connection but when i change connections in Identity models to mine, it stops working.
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("IdentityDbContext", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
}
Try to use Automatic migration
I am writing an application using the VS2013 SPA template that includes Asp.NET Identity, WebAPI2, KnockoutJS and SqlServer Express 2012.
I started off using the IdentityUser class to handle my users and that worked just fine. I was able to add and login as a user with no problem. I then wanted to add custom information to the IdentityUser (there was an article I can no longer find).
As a result, I created an User class that inherited from IdentityUser as seen below.
public class User : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Then I updated all the references in the project from IdentityUser to User.
Now, whenever I try to login I get the following error:
The entity type User is not part of the model for the current context.
The thing is, I have a DBInitializer (public class ApplicationDBInitializer : DropCreateDatabaseAlways<ApplicationDBContext>) that always recreates the database and adds some test users and the tables are created and the users are added successfully.
On the off chance it matters, here is my cxn string: <add name="DefaultConnection" connectionString="Server=.\SQLEXPRESS;Database=ibcf;Trusted_Connection=True;" providerName="System.Data.SqlClient" />
and my DBContext
public class ApplicationDBContext : IdentityDbContext<User>
{
public ApplicationDBContext()
: base("DefaultConnection")
{
}
}
Why is this error happening?
The issue was that the Startup.Auth.cs continued to reference the default IdentityDbContext<User> DB context. After updating the class to reference my ApplicationDBContext the issue was resolved.
static Startup()
{
...
UserManagerFactory = () => new UserManager<User>(new UserStore<User>(new ApplicationDBContext()));
...
}
I have Solution consisting of 3 projects, first is Data Access Layer (where models and Database Context are defined), and other two are Asp.net MVC 5 and Asp.net Web Api 2 projects.
For authentication and authorization I'm using Asp.net Identity which I've set up like this (in my DAL project):
public class DatabaseContext : IdentityDbContext<User>
{
public DatabaseContext()
: base("DefaultConnection")
{
Configuration.LazyLoadingEnabled = true;
}
public DbSet<IdentityUser> IdentityUsers { get; set; }
/*
Other DbSets ...
*/
}
My User class extends IdentityUser.
In my ASP.net project I've changed a bit Account controller so it works with my Database Context, here are relevant parts which I changed:
[Authorize]
public class AccountController : Controller
{
public AccountController()
: this(new UserManager<User>(new UserStore<User>(new DatabaseContext())))
{
}
public AccountController(UserManager<User> userManager)
{
UserManager = userManager;
}
public UserManager<User> UserManager { get; private set; }
}
And this part works fine. So my question is, what changes I have to do in order my Web API project works with my entity User and my Database Context, so in order to consume API user must be logged in ? (and of-course user has option to register via API).
I.E. I want to enable authorization and authentication for web api 2 by using my Database Context and class User which extends Identity User class.
UPDATE
What I've tried to do is this: I've replaced all IdentityUser classes in my web api 2 project with my class User, but on line (when I try to log in):
User user = await userManager.FindAsync(context.UserName, context.Password);
I get error:
System.Data.SqlClient.SqlException: Invalid object name 'dbo.AspNetUsers'.
This approach worked for my asp.net MVC project.
In short what I did was:
In my DatabaseContext class I've added these lines:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>()
.ToTable("AspNetUsers");
modelBuilder.Entity<User>()
.ToTable("AspNetUsers");
}
In asp.net web api project I've changed all classes IdentityUser to User, and that's it