Security and authorization using Roles

0

I am terminating my application by configuring the authorization and permission of the application users. My idea is to tinker with the layout so that the menus and submenus are only visible to those who have permission for it. According to what I researched I need to create Roles to assign in my layout

 @if (User.IsInRole("Usuário")

Well then. I have 3 tables in my bank prepared to make this control. Follow my models.

    public class Perfil
{
    public int Id { get; set; }

    public string Matricula { get; set; } // Esse campo é o mesmo de login do usuário no sistema

    public string Nome { get; set; }

    public virtual ICollection<PerfiRole> PerfilRoles { get; set; }
}


    public class Role
{
    public int RoleId { get; set; }

    public string Nome { get; set; } // Administrador, Gerente, Usuário

    public virtual ICollection<PerfiRole> PerfilRoles { get; set; }
}


    public class PerfiRole
{
    [Key]
    public int PerfilRoleId { get; set; }

    public int Roleid { get; set; }
    public virtual Role Role { get; set; }

    public int Perfilid { get; set; }
    public virtual Perfil Perfil { get; set; }

    public int Matricula { get; set; }



}

All tables are already loaded with their proper Administrator, User, and Manager profiles and assignments. I am using windows authentication where the Profile table field is the same as the user input in windows, and when it accesses the application, it already opens with its Profile data pulled from the login without needing 'user and password' to enter the application. Anyway, from this I wanted to close the mechanism for when the user enters the application, load your data automatically as it is already done and only appear the menus corresponding to your profile as already defined in the database. I would like to know how the controller is so I can do this. I tried a few methods and saw some examples but none resembled what I need. I also need to know what to change in webconfig. All help and suggestions are welcome

EDIT

    public class CustomRoleProvider : RoleProvider
{

    public override string ApplicationName
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    {
        throw new System.NotImplementedException();
    }

    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
    {
        throw new System.NotImplementedException();
    }

    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
    {
        throw new System.NotImplementedException();
    }

    public override bool IsUserInRole(string username, string roleName)
    {
        throw new System.NotImplementedException();
    }

    public override void CreateRole(string roleName)
    {
        throw new System.NotImplementedException();
    }

    public override string[] FindUsersInRole(string roleName, string usernameToMatch)
    {
        throw new System.NotImplementedException();
    }

    public override string[] GetUsersInRole(string roleName)
    {
        throw new System.NotImplementedException();
    }

    public override bool RoleExists(string roleName)
    {
        using (var db = new DataContext())
        {
            // check if role exits
            return db.Roles.Any(r => r.Nome == roleName);
        }
    }

    public override string[] GetAllRoles()
    {
        List<string> roles = new List<string>();

        using (var db = new DataContext())
        {
            try
            {
                var dbRoles = db.Roles.ToList();

                foreach (var role in dbRoles)
                {
                    roles.Add(role.Nome);
                }
            }
            catch (Exception e) { throw e; }
        }

        return roles.ToArray();
    }

    public override string[] GetRolesForUser(string username)
    {
        List<string> roles = new List<string>();

        using (var db = new DataContext())
        {
            try
            {
                var dbRoles = db.Perfis.Where(p => p.Matricula == username).ToList();

                foreach (var role in dbRoles)
                {
                    roles.Add(role.Nome);
                }
            }
            catch (Exception e) { throw e; }
        }

        return roles.ToArray();
    }

}
    
asked by anonymous 16.07.2014 / 16:34

1 answer

4

Part of the answer I'm going to describe here begins in this other answer that I did, explaining the entire Membership topology schema . Skipping to the part that interests you, implement the following:

1. CustomRoleProvider

It does not have to be this name. It can be any other. No scheme to update your Web.config , but the general idea is that this derived class has the following:

public class CustomRoleProvider : RoleProvider
{
    // A interface pede a declaração explícita de ApplicationName, mas a 
    // implementação é opcional. Apenas declare para evitar erros.
    public override string ApplicationName
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    // Este método adicionará vários usuários a várias roles.
    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    { ... }

    // Este método cria uma Role
    public override void CreateRole(string roleName)
    { ... }

    // Este método exclui uma Role
    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
    { ... }

    // Este método encontrará usuários que batam com uma determinada expressão
    // passada por parâmetro
    public override string[] FindUsersInRole(string roleName, string usernameToMatch)
    { ... }

    // Este método devolverá todas as Roles
    public override string[] GetAllRoles()
    { ... }

    // Este método devolverá todas as Roles de um usuário
    public override string[] GetRolesForUser(string username)
    { ... }

    // Este método devolverá todos os usuários de uma Role
    public override string[] GetUsersInRole(string roleName)
    { ... }

    // Este método verifica se um usuário pertence a uma Role
    public override bool IsUserInRole(string username, string roleName)
    { ... }

    // Este método remove os usuários das Roles passadas como parâmetro
    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
    { ... }

    // Este método verifica se uma Role existe.
    public override bool RoleExists(string roleName)
    { ... }
}

2. Web.config

Add the following to your Web.config :

<configuration>
  <system.web>
    <roleManager enabled="true" defaultProvider="CustomRoleProvider">
      <providers>
        <clear />
        <add name="CustomRoleProvider" type="MeuProjeto.Site.Infrastructure.CustomRoleProvider" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </roleManager>
  </system.web>
<configuration>

3. Implement the methods according to your topology

Now just implement. I'll give you some examples within your topology:

    public override string[] GetAllRoles()
    {
        List<string> roles = new List<string>();

        using (var context = new MeuProjetoContext())
        {
            try
            {
                var dbRoles = context.Roles.ToList();

                foreach (var role in dbRoles)
                {
                    roles.Add(role.Nome);
                }
            }
            catch (Exception e) { throw e; }
        }

        return roles.ToArray();
    }

    // Estou supondo aqui que "User", no seu caso, é "Perfil"
    public override string[] GetRolesForUser(string username)
    {
        List<string> roles = new List<string>();

        using (var context = new MeuProjetoContext())
        {
            try
            {
                var dbRoles = context.Perfis.Where(p => p.Nome == username).ToList();

                foreach (var perfilRole in dbRoles.Select(r => r.PerfilRole))
                {
                    roles.Add(perfilRole.Role.Nome);
                }
            }
            catch (Exception e) { throw e; }
        }

        return roles.ToArray();
    }

If you need more examples, I will improve the answer.

    
16.07.2014 / 19:35