0

TL;DR

EDit

Basically, I just want to tell to some function : Ok, I've checked this user my self, he's ok. Now store some arbitrary data about him and create a session for him that gives him permissions to access certain parts of my app.

something of this sort :

logInUserFrameworkFunction(new UserStruct(int id, string username, RolesEnum[] roles));

And than everything is handled in the background to make [Authorize(Roles = RolesEnum.Admin | RolesEnum.Manager)] attribute work.

I could make this with sessions my self but I would like to skip that part :D


I'm playing with MVC and Entity Framework, and now I'd like to implement simple user authentication with roles.

I have User class / table in my database that looks something like this :

public class User {
    int ID;
    string Email;
    string Password;
    Role Role;
...
}

And Role class that looks like this :

public class Role {
    int ID;
    RoleType Type; // this is an Enum
}

public Enum RoleType {
    visitor, employee, admin
}

Now, checking in login controller if user with specified username and password exists is easy, I just do something like this :

[HttpPost]
    public ActionResult LogIn(LogIn login) {
        // If credentials are valid
        if(new UserManager().IsValid(login.Username, login.Password)) {
            var user = db.getUserByEmail(login.Username);
...

I could easily store user ID and Role in session and than check credentials by calling some function on every relevant controller but I want to use some of C# and MVC features.


Thing is that I would rather do it with attributes, but I'm not sure how.

This is what I imagined it would look like :

[Roles(RoleType.visitor, RoleType.employee)]
public ActionResult SomeProtectedAction() {
// only employee and visitor can access this,
// others get redirected to where ever
...
}

1 Answer 1

1

You can authorize using Roles like this:

[Authorize(Roles= MyEnum.Admin | MyEnum.Moderator)]
public ActionResult myAction()
{
}

The Authorize attribute is here applied at controller level, but you can apply it only to action methods, depending on your needs.

Provided you have setup your authentication logic correctly (ASP.NET Identity) which will return an authentication cookie including user roles. Now after successful login, if you make a request to a controller method, the cookie is unpacked in the background and the User property this.User is filled with this data including roles of that user.

The authorize attribute will do the check for you automatically.

Sign up to request clarification or add additional context in comments.

3 Comments

This is a real power of Roles, in which you can provide a large-scale access to the controller, and then narrow the access on a per-method level. So let’s say you have a role called Staff, which needs to access a controller (the entire controller is decorated so anyone in Staff role can access it). But let’s say you want to limit deletion capabilities to Admins only, so you decorate the deletion methods with the Admin role specifically so that only people who are both Staff and Admins can delete. People who are just Staff and Users cannot. (Business logic: 2 roles req. for every account)
I get how I can use roles like this, but how do I log in my user. Is there a function like this one that I can call? : identityLoginUser(new identityUser(int id, string username, RolesEnum[] roles), and than he makes cookie in the background and everything is working with minimal effort?
It's good if you understand the basics of ASP.NET Identity :-) Look here and search for "Sign-In Helper - The Basic Identity 2.0 Sign-In API". This v2.0, there is a newer one, but it should be not very much different.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.