Security and authorization using Roles

Asked

Viewed 1,287 times

1

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

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

Well done. I have 3 tables in my bank prepared to do 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 profiles and roles of Administrator, User and Manager. I am using windows Authentication where the Profile table Register field is the same as the user input in windows, and when this accesses the application, it already opens with its Profile data pulled from login without the need of 'user and password' to enter the application. Finally, from this I wanted to close the mechanism so that when the user enters the application, load his data automatically as it is already done and appear only the menus corresponding to his profile as already defined in the database. I’d like to know what the controller looks like so I can do that. I tried some methods and saw some examples but none similar to what I need. I also need to know what to change in webconfig. All help and suggestion is 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();
    }

}
  • You implemented a RoleProvider so that command User.IsInRole() work properly?

  • No, that’s what I need to know how to implement.

  • Or @Ciganomorrisonmendez if there is another way I can do the same without the need to [Roleprovider]

  • The best way is by using the RoleProvider. See the answer.

1 answer

5

Part of the answer that I will describe here begins in this other answer I made, explaining the whole scheme of Membership topology. Skipping to the part that matters, implement the following:

1. Customroleprovider

It does not need 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 methods according to their topology

Now just implement. I’ll give 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’ll improve the answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.