Get Logged in User Role: Asp.net MVC5 - c#

I have a doubt. I am using Asp.net mvc5 in VS2013. When the user is logged in, username of the logged in user can be identified using,
User.Identity.GetUserId
But i couldn't be able to identify the role of the user in the view page.
I tried the following:
#{
var store = new Microsoft.AspNet.Identity.EntityFramework.UserStore<RaspberryPi.Models.ApplicationUser>(new RaspberryPi.Models.ApplicationDbContext());
var manager = new Microsoft.AspNet.Identity.UserManager<RaspberryPi.Models.ApplicationUser>(store);
var l = manager.IsInRole(User.Identity.GetUserId, "Moderator");
}
But resulted in error.
CS1928: 'Microsoft.AspNet.Identity.UserManager<RaspberryPi.Models.ApplicationUser>' does not contain a definition for 'IsInRole' and the best extension method overload 'Microsoft.AspNet.Identity.UserManagerExtensions.IsInRole<TUser>(Microsoft.AspNet.Identity.UserManager<TUser>, string, string)' has some invalid arguments
How can i do that?
Please help,
Thanks

The exception is pretty self explanatory really, the parameters you are providing do not tie up with the IsInRole extension method.
The problem (assuming your code is exactly as you have shown) is thatGetUserId is a function, not a property, therefore you need to actually call it
manager.IsInRole(User.Identity.GetUserId(), "Moderator");

Does your ApplicationUser derive from IdentityUser?
public class ApplicationUser : IdentityUser
This should work in the cshtml
#{
var context = new RaspberryPi.Models.ApplicationDbContext();
if (context.Users.Any(u => u.UserName == User.Identity.Name))
{
var store = new Microsoft.AspNet.Identity.EntityFramework.UserStore<applicationuser>();
var manager = new Microsoft.AspNet.Identity.UserManager<applicationuser>(store);
ApplicationUser user = manager.FindByName<applicationuser>(User.Identity.Name);
if (manager.IsInRole(user.Id, "Moderator") == true)
{
// Do whatever you want...
}
}
Or if you want to do it the simple way just do this.
#if (User.IsInRole("Moderator")){
}

Related

Inserting a row into Relational database table

I am very new to c# and asp.net mvc. I'm building a HR portal for our company where a user can submit a leave form among other things... So I'm using mssql as the database server and using Entity Frame work to communicate with it. I have 3 entities, user (Containing user details), permissions (the user permissions for allowing actions in the app) and then the leave form table (where the leave form details are stored). There is a one to many relationship between user - permission and then a one to many relationship between user-leave. I am not fazed about the permissions as that gets created when the user account is being created.
The problem I am facing is, how do I add a leave form for a specific user? Below is my controller code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Leave(MasterViewModel model)
{
DocSubViewModel mv = model.DSModel;
int userId = Convert.ToInt32(Session["userID"]);
try
{
using (HrDcpDBContainer db = new HrDcpDBContainer())
{
var leave = db.leaves.Create();
leave.dateFrom = mv.DateFrom;
leave.dateSubmitted = DateTime.Now;
leave.dateTo = mv.DateTo;
leave.nrDays = mv.NrDays;
leave.reason = mv.SpecialLeave;
leave.TLApproval = null;
leave.TLApprovalDate = null;
leave.TLApprovalID = mv.TeamLeaderID;
leave.DMApprovalDate = null;
leave.DMApprovalID = mv.DepManagerID;
leave.DMApproval = null;
leave.type = mv.Type;
leave.user = userId;
db.leaves.Add(leave);
db.SaveChanges();
}
ViewBag.Message = "Leave Form submitted Successfully. You will be redirected shortly...";
return View("result");
}
catch (Exception ex)
{
ViewBag.Message = ex;
//ViewBag.Message = "Leave Form submitted Successfully. You will be redirected shortly...";
return View("result");
}
The problem comes in leave.user = userId;. It says:
Cannot implicitly convert int to Portal.Model.user
I can't seem to find out how to do this...
You're telling it to put the UserId where your leave model is asking for a User.
Your relationship requires a User to go in there, so you'll have to update your code a little bit:
using (HrDcpDBContainer db = new HrDcpDBContainer())
{
var leave = db.leaves.Create();
leave.user = db.users.First(x => x.Id == userId);
}
This will put reference to the actual user in the new leave record. If you go later and check it out you'll see a column in the leave table called user_Id that has an integer value in it and is set as a foreign key to the users table.
Note that this will error if no user exists having the specified Id value. If you anticipate this to be a problem, rather use .FirstOrDefault() instead of .First() and then account for the value being null before you add it to your new leave object.
That's expected since User is a object and not int. What you should be doing probably is leave.user.UserId = userId; instead [Assuming leave.user is of type User which has a UserId property]

Can not find data from the dbcontext with linq

I am trying to develop a "password reset" functionality. To achieve this, I am generating a guid when a user requests a password reset and send this as an email, with a link to the password reset page, that has the guid as a query string.
The code I have written is below:
Request.QueryString[BusinessLayerConstants.resetPasswordQueryString]) ? Request.QueryString[BusinessLayerConstants.resetPasswordQueryString] : String.Empty;
passwordCode = System.Web.HttpUtility.UrlDecode(passwordCode);
using (DBEntities entities = new DBEntities())
{
User = entities.AspNetUsers.FirstOrDefault(u => u.PasswordReset == passwordCode);
if (User != null)
{
//TODO
}
}
The problem is, linq always returns null. If I run a SQL command in the database with the same guid, I am able to see the data. And the passwordCode variable is getting the right value as well. I have even checked if the passwordCode has some hidden characters because it is coming from the query string; but it is also fine.
I am also using this exact same logic for activation as well. I am passing a guid as a query string, and for activation, I am able to find the data with the following code:
AspNetUser user = entities.AspNetUsers.FirstOrDefault(u => u.ActivationCode == activationCode);
It is not working for the password, I have also tried using .Equals() and .Contains() with no luck.
If anyone has any idea what might be wrong, I would appreciate any help. Thanks.
EDIT:
PasswordReset is just some GUID I generate to pass as a querystring.
Everything is fine when I do this:
But in the code, the code I have written returns null:
Remember that C# is case sensitive you should do like:
Request.QueryString[BusinessLayerConstants.resetPasswordQueryString]) ? Request.QueryString[BusinessLayerConstants.resetPasswordQueryString] : String.Empty;
passwordCode = System.Web.HttpUtility.UrlDecode(passwordCode);
using (DBEntities entities = new DBEntities())
{
User = entities.AspNetUsers.FirstOrDefault(u => u.PasswordReset.ToLower() == passwordCode.ToLower());
if (User != null)
{
//TODO
}
}

How to check if an azure active directory user is already in an approle

I've created an Azure active directory user and added the user to app roles.
Now i am retrieving this user and attempting to add it to more app roles.
var activeDirectoryUser = client.Users.Where(u => u.UserPrincipalName == user.UserName).ExecuteSingleAsync().Result as User;
As a precaution i want to first check if the user is already in an app role before adding however the problem is that the ApproleAssignments field on the User object is always empty. Even thou the user has app role assignments and i get an error if i try and add the user to the same app role.
Creating new app role assignment.
var appRoleAssignment = new AppRoleAssignment
{
Id = appRole.Id,
ResourceId = Guid.Parse(servicePrincpal.ObjectId),
PrincipalType = "User",
PrincipalId = Guid.Parse(user.ObjectId)
};
if(IsUserInAppRole(user,appRoleAssignment))return;
user.AppRoleAssignments.Add(appRoleAssignment);
user.UpdateAsync().Wait();
Checking if user is in app role.
private bool IsUserInAppRole(User user, AppRoleAssignment appRoleAssignment)
{
var userInApprole = user.AppRoleAssignments.Where(ara => ara.ObjectId == appRoleAssignment.Id.ToString());
return userInApprole.Any();
}
I'm using the latest version of Microsoft.Azure.ActiveDirectory.GraphClient library
Sorry for the late response. The following code worked for me. Not sure if you need to use the IUserFetcher interface, but your LINQ query fails because you are comparing the objectID of the assignment, with the appRole Id. What you need to compare is the ID of the assignment.
var userFetcher = user as IUserFetcher;
IPagedCollection<IAppRoleAssignment> rawObjects = userFetcher.AppRoleAssignments.ExecuteAsync().Result;
IList<IAppRoleAssignment> assignments = rawObjects.CurrentPage.ToList();
IAppRoleAssignment a = null;
a = assignments.Where(ara => ara.Id.Equals(appRole.Id)).First();
if (a != null) {
Console.WriteLine("Found assignment {0} for user {1}", appRole.Id, user.DisplayName);
}
Hope this helps...
var userFetcher = user as IUserFetcher;
IPagedCollection rawObjects = userFetcher.AppRoleAssignments.ExecuteAsync().Result;
IList<IAppRoleAssignment> assignments = rawObjects.CurrentPage.ToList();
Above lines of code is causing exception due to casting not done, if cast it as:
IPagedCollection rawObjects =
(IPagedCollection)userFetcher.AppRoleAssignments.ExecuteAsync().Result;
IList<IAppRoleAssignment> assignments =
(IList<IAppRoleAssignment>)rawObjects.CurrentPage.ToList();
Code get compiled successfully but gives runtime exception as:
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.IList'. An explicit conversion exists (are you missing a cast?)
Could you please guide how to use those two statements?
Update:
private static bool IsUserInRole(User user, AppRole appRole, bool roleAlreadyAssigned = false)
{
var userFetcher = user as IUserFetcher;
IPagedCollection rawObjects = (IPagedCollection)userFetcher.AppRoleAssignments.ExecuteAsync().Result;
foreach (IAppRoleAssignment item in rawObjects.CurrentPage)
{
if (item.Id == appRole.Id)
{
roleAlreadyAssigned = true; break;
}
}
return roleAlreadyAssigned;
}
The above code worked for me. Try this, hope this will help :)

How to store login user id in asp.net?

i am new to asp.net. my question is that how one can save login userid in asp.net webform?
code i am writing in asp.net webform is:
foreach (var s in db.Users)
{
if (tbUserName.Text==s.user_name && tbPassword.Text == s.user_password)
{
if (string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
{
FormsAuthentication.SetAuthCookie(tbUserName.Text, false);
Response.Redirect("~/");
}
else
{
FormsAuthentication.RedirectFromLoginPage(tbUserName.Text, false);
}
flag = 1;
break;
}
else
flag=0;
}
if(flag==0)
{
tbUserName.ErrorText = "Invalid user";
tbUserName.IsValid = false;
}
}
As Tim said, you can get the authenticated user with
User.Identity.Name
You can also get the AuthenticationType and IsAuthenticated properties from the same object.
A suggestion would be to NOT query your DB for all of the users and then loop through them for the correct one. Based off of the user input, you should query the db for the one and only user which matches the form post.
Based off of what you wrote, it looks like the passwords are in clear text and not encrypted, which is a huge security issue. Being new to .Net, take a look at the .Net Membership Providers or SimpleMembership or a comparable pattern.
Good luck!
I would suggest you look at using the Session object to store the user ID. A Session will be available throughout that user's session on the site. Thus, you can call Session anywhere in your site's code to reference that user ID.
For example, to store the id, simply do this, pretend we're in Page_Load()
Session["UserId"] = userID // Or wherever you get the ID from.
then in your code behind, you can do this:
string userId = Session["UserId"]
If the user ID is a number, say an int, then you will need to cast the userID:
int userId = 0;
int.TryParse(Session["UserID"], out userID)
Quick dirty link to a Session example :
http://asp.net-tutorials.com/state/sessions/

How can i get entire role assignments from SP 2010 using C# and the client object model interface?

I've been trying to get all the RoleAssignments using the COM interface. the problem is that i get the AD user group names instead of the actual users inside the groups.
my code looks something like this:
ClientContext cc = new ClientContext(#SiteURL);
RoleAssignmentCollection Roles = cc.Web.RoleAssignments;
IEnumerable<RoleAssignment> newRoleAssignmentsCollection = cc.LoadQuery(Role.Include(role => role.Member));
AsyncDelegate execDel = new AsyncDelegate(cc.ExecuteQuery);
execDel.BeginInvoke(arg => { cc.ExecuteQuery();
foreach (RoleAssignment RoleAssign in newRoleAssignmentsCollection)
{
RoleAssign.Member.LoginName; // <------- Here is my problem!!!
}
}, null);
Can anyone please tell me how to get the users which are inside the Active Directory group?
Thanks in advance, Itay.

Categories