Net core custom user property - asp.net

I'm using the default authorization in my .NET Core project. I want to check if an user is admin so in ApplicationUser.cs model I've added this:
public class ApplicationUser : IdentityUser
{
public bool admin { get; set; }
}
I migrated these changes into my SQL database and I can see the 'admin' property inside the AspNetUsers table. How do I check the 'admin' property of the currently logged in user?

You can access the current user instance through the UserManager<T> object, which can be injected into your controller as a constructor parameter. The method GetUserAsync takes a ClaimsPrincipal, which in this case is the User of the HttpContext.
private readonly UserManager<ApplicationUser> _userManager;
public HomeController(UserManager<ApplicationUser> userManager) {
_userManager = userManager;
var user = _userManager.GetUserAsync(HttpContext.User);
}

I agree with the above answer by Peter to just use the user variable and check for user.admin, however, I strongly suggest extending your project to use a simple Role-based Authorization to simplify things in the long run. You can achieve this with the following documentation: https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles

Related

Retrieve user information from ASPNetUsers table

I am really new to using Blazor WASM and the ASP.NET Core hosted. I have set up the login which stores all registered users to the ASPNetUsers table. I am wondering how I can then retrieve these users to display information to other users. For example I am looking to be able to have a user logged in who can then search all other users who have registered into the application as well. How might I go about displaying a list of all the users who have registered onto the application, stored in ASPNetUsers table
Options
Retrieve and send back
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> Get()
{
var result = userManager.Users.FirstOrDefault();
User x = new User();
x.Username = result.Email;
List<User> giveback = new List<User>();
giveback.Add(x);
return giveback;
}
To retrieve all users access the Users property on the UserManager:
var users = UserManager.Users.ToList();
The image in your post shows that you are only accessing the static members. You are not using an instance of UserManager.
You need to inject an instance into your controller:
readonly UserManager<ApplicationUser> _userManager;
public MyController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
[HttpGet]
public ActionResult<IEnumerable<Ticket>> Get()
{
var user = _userManager.Users.FirstOrDefault();
}

how implement exiting authentication roles in the database into AspNet IdentityRole

i've asp mvc application , database first , i have a table to hold my roles another for my users and junction table user_role.
i added the following class to my app
Microsoft.AspNet.Identity.Owin
Microsoft.AspNet.Identity.EntityFramework
Microsoft.Owin.Host.SystemWeb
can i use my existing tables to apply the roles to my controllers
[Authorize(Roles = "Admin")]]
public ActionResult MySecretAction() {}
or maybe
[Authorize(Roles = MyDBEntities.Roles.Find(1)]]
public ActionResult MySecretAction() {}
thank you
Can I use existing roles from db table?
Yes you can use existing roles from database.
You can use [Authorize(Roles = "Admin")], but not [Authorize(Roles = MyDBEntities.Roles.Find(1)] as it is not constant value, but dynamic.
But how can I add and remove roles to my existing tables when I assign a role to a user?
To add new role(s) you have to use RoleManager class with CreateAsync method along with other methods for managing roles used by your app.
When i add a role to a method , and the user is not authorized to use it , the application redirects him back to the login page ,where to change this?
To alter behavior during athorization you have to implement own Authorization attribute inherited from AuthorizeAttribute and override OnAuthorization method.
public class AuthorizeRoleAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// User is not authenticated(NOT logged in)
// we are letting ASP.NET to use standard procedure => redirect her/him to login page
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
base.HandleUnauthorizedRequest(filterContext);
}
// User is authenticated(logged in)
// we are going to show her/him custom view with error
else
{
// Don't forget to create Unauthorized.cshtml view in Shared folder
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Shared/Unauthorized.cshtml"
};
}
}
}
Then you have to use your custom AuthorizeRoleAttribute instead the default one.
[AuthorizeRole(Roles = "Admin")]]
public ActionResult MySecretAction() {}
Resources:
RoleManager class
Implementing RoleManager in ASP.NET MVC 5
ASP.NET MVC 5 Identity: Extending and Modifying Roles
I've created a costume authorization class , witch i can user to access the logged in user and my databases tables
using System;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using System.Linq;
using System.Collections.Generic;
using LoanApp.Models.DataBaseModel;
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DynamicAuthorize : AuthorizeAttribute
{
// public string DefaultURL { get; set; }
protected override bool AuthorizeCore(HttpContextBase context)
{ return true;
}
}

How to set a privilege inside a role in ASP.NET MVC?

I currently have a system where there is a user table, a role table, and a user-roles association table, where one user can be associated to multiple roles (like Admin, BasicUser, etc.). I am able to authorize action methods based on these roles. This is from the Identity framework.
Now I want to add support for privileges so that action methods can be restricted based on those as well, rather than just by roles. For example, in a Controller, I may have an HTTPPost action that only someone with a "Write" privilege should be able to perform successfully.
What changes do I need to make so that I can assign privileges to roles? I.E., I want to select the "Admin" role to have the "Write" and "Read" privileges, while a "BasicUser" role will only be assigned a "Read" privilege. This way, an Admin can access any method that is allowed by the Write privilege, while the BasicUser can not.
If I were to create another table called "Privilege" and an association table between that and roles, and the code to set privileges in a role, how can I use the privilege as a filter? So for example, the below action should only be allowed to be performed by a user in a role that has the "Write" privilege attributed to it.
[Write]
public ActionResult Create()
{
return View();
}
Thank you.
The same way the AuthorizeAttribute works, you can create a custom authorization attribute inheriting from it:
public class AuthorizePrivilegeAttribute : AuthorizeAttribute
{
// Custom property
public string Privilege { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// Reusing default authentication.
var isAuthorized = base.AuthorizeCore(httpContext);
if (!isAuthorized)
{
return false;
}
return YourCustomCode.HasPrivilege(this.Privilege))
}
}
Then using it on top of your method:
[AuthorizePrivilege(Privilege = "Write")]
public ActionResult Create()
{
return View();
}

ASP.NET Identity 2.0 UserManager.FindByIdAsyc not returning Roles

I am building a website using ASP.NET MVC v5.2, Entity Framework v6.0 (Code First) and Identity 2.0.
I have the following code in my UserAdmin controller:
// GET: /UserAdmin/Details/5
public async Task<ActionResult> Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(id);
return View(user);
}
My problem is that while I can populate a user's roles with the UserManager, it is not picking up the roles associated with that user when using the FindByIdAsync method.
Here is data from the IdentityUserRole table which shows for the highlighted user assigned to two roles:
Here is the debug info showing the same user as above but the Roles count is zero:
Why are the roles for this user not being returned?
Edit #1
I am not using the default implementations for UserManager.
My ApplicationUser extends IdentityUser to allow me to add custom properties. My ApplicationDbContext extends IdentityDbContext.
Here's where I set up my primary keys for Identity using Fluent API:
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
As you are extending the IdentityDbContext and IdentityUser, you don't need to define your relationships for Logins, Roles and UserRoles as they are already defined in the base classes. You need to remove the lines like modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId }); as they are taken care of.
As for not using the default UserManager There is a possibility here I see based on the code you have provided.
The default implementation for UserManager takes an IUserStore<TUser> as a parameter in it's constructor. If you are using (or deriving from) the UserStore<TUser> implementation in the Microsoft.AspNet.Identity.EntityFramework Library, the things like Roles, Claims and Logins are being included in the queries being made to the database. If you are creating your own class implementing IUserStore<TUser> then you will need to include the related data yourself. an example is shown below.
public class ApplicationUser : IdentityUser
{
//Add your Custom Properties here..
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
//Add your Custom Properties here..
}
public class ApplicationUserStore : IUserStore<ApplicationUser>
{
private readonly ApplicationDbContext _context;
public ApplicationUserStore(ApplicationDbContext context)
{
_context = context;
}
public async Task<ApplicationUser> FindByIdAsync(string userName)
{
return await _context.Users.Include(x => x.Roles).FirstOrDefaultAsync(n => n.UserName == userName);
}
}

What Type (class) do i use for a property in my POCO for Asp.net Identy User

I have a codefirst POCO, and i want to specify a LastEditUser from my current ASP.NET IDENTITY user. I tried type ApplicationUser that gets generated with the new project. but it just saves as null.
Here is my current Attempt
public class SomeClass
{
public string SomeProperty { get; set; }
public ApplicationUser LastEditMember { get; set; }
}
And here is how i try to save it in my controller.
string currentUserId = User.Identity.GetUserId();
ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);
instannceOfSomeClass.LastEditMember = currentUser;
After loading this again. the LastEditMember property is null.
I would suggest using the UserManager class to get the user object instead of working with the DbContext object. You can use UserManager.FindByIdAsync(currentUserId) to get the user. Also I am considering that this code is hit only after a user logs into the application else the currentUserId will be null

Resources