Custom Roleprovider

Asked

Viewed 541 times

7

I am implementing an authentication with RoleProvider Custom.

I have a class Usuario and a class Role with Many to Many relationship.

I created a folder in the project called Security and inside the folder a class called PermissaoProvider that extends the class RoleProvider.

The only method I have subscribed to and the method below:

public override string[] GetRolesForUser(string username)
{
    var context = new RdpContext();
    var user = context.Usuarios.SingleOrDefault(u => u.Login == username);

    if (user == null)
    {
        return new string[] { };
    }

    var roles = user.Roles.Select(r => r.Nome).ToList();
    return roles.ToArray();
} 

I also created a class called Permissionsfield which follows below:

public class PermissoesFiltro : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if (Repositorios.UserRepositorio.GetUsuarioLogado() != null)
        {
            if (filterContext.Result is HttpUnauthorizedResult)
            {
                filterContext.HttpContext.Response.Redirect("/admin/Home/Negado");
            }
        }
        else
        {
            filterContext.HttpContext.Response.Redirect("/admin/login");
        }
    }
}

And then I decorate my Controller as follows:

[PermissoesFiltro(Roles = "ADM, USER")]
public ActionResult Index()
{
    return View();
}

Authentication happens normally, but regardless of which user Log and always redirected to the denied access page, follows below the authentication methods.

public class UserRepositorio
{
    public static Usuario GetUsuarioLogado()
    {
        var usuario = HttpContext.Current.Request.Cookies["UserCookieAuthentication"];

        if (usuario == null)
        {
            return null;
        }

        var novoToken = CryptographyRepository.Descriptografar(usuario.Value);
        int usuarioId;

        return int.TryParse(novoToken, out usuarioId) ? GetUsuarioById(usuarioId) : null;
    }

    public static Usuario GetUsuarioById(int usuarioId)
    {
        var context = new RdpContext();

        var usuario = context.Usuarios.Include("Roles").FirstOrDefault(u => u.UsuarioId == usuarioId);

        return usuario;
    }

    public static bool AutenticaUsuario(string login, string senha)
    {
        var ctx = new RdpContext();
        ctx.Configuration.ProxyCreationEnabled = false;

        try
        {
            var usuario = ctx.Usuarios.SingleOrDefault(u => u.Login == login && u.Status);

            if (usuario == null)
            {
                return false;
            }

            if (!Crypto.VerifyHashedPassword(usuario.Senha, senha)) return false;

            var userCookie = new HttpCookie("UserCookieAuthentication")
            {
                Value = CryptographyRepository.Criptografar(usuario.UsuarioId.ToString(CultureInfo.InvariantCulture)),
                Expires = DateTime.Now.AddDays(1)
            };

            HttpContext.Current.Response.Cookies.Add(userCookie);

            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }

    public static void LogOff()
    {
        var usuario = HttpContext.Current.Request.Cookies["UserCookieAuthentication"];

        if (usuario == null) return;

        var userCookie = new HttpCookie("UserCookieAuthentication")
        {
            Expires = DateTime.Now.AddDays(-1)
        };

        HttpContext.Current.Response.Cookies.Add(userCookie);
    }
}

I also set up web.config as follows::

<roleManager defaultProvider="PermissaoProvider" enabled="true"  cacheRolesInCookie="true">
      <providers>
        <clear/>
        <add name="PermissaoProvider" 
             type="App.Rdp.Security.PermissaoProvider" 
             connectionStringName="RdpContext"
             applicationName="/"
             enablePasswordRetrieval="false" 
             enablePasswordReset="true"
             requiresQuestionAndAnswer="false" 
             writeExceptionsToEventLog="false"/>
      </providers>
    </roleManager>

I am 2 days researching and can not find a solution.

1 answer

2


The problem is in your PermissoesFiltro: the event OnAuthorize calls another call called AuthorizeCore, which effectively calculates the permission. I would override it so:

public class PermissoesFiltro : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var baseReturn = base.AuthorizeCore(httpContext);

        var permissionsReturn = false;
        /* Insira aqui sua lógica para modificar permissionsReturn para true */

        return baseReturn && permissionsReturn;
    }
}
  • I’ll be honest, I didn’t quite understand how to do this implementation, I researched Authorizecore and I couldn’t understand how it works! =/

  • It’s simple: it returns true whether the user is authenticated and false otherwise. What you have to do is a logic that checks all the steps you consider the user needs to go through to be considered authenticated by the system.

  • The Code I posted is authenticating, when authenticating it takes the user with all his permissions, but it always falls into the method of unauthorized.

  • So, but to consider authenticated, you have to go through AuthorizeCore.

Browser other questions tagged

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