Pergunta

Sou novo usuário do MVC 3 e estou tentando fazer administração através do banco de dados SQL.Em primeiro lugar, tenho a entidade Cliente e o administrador pode ser definido através do campo admin, que é do tipo booleano na entidade Cliente.Quero fazer para acessar o administrador apenas na página do produto, não no cliente normal.E eu quero fazer [Authorize(Roles="admin")] em vez de [Authorize].No entanto, não sei como posso realmente definir a função de administrador em meu código.Então, no meu HomeController, escrevi este código.

public class HomeController : Controller
{

    [HttpPost]
    public ActionResult Index(Customer model)
    {
        if (ModelState.IsValid)
        {
            //define user whether admin or customer
            SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["rentalDB"].ToString());
            String find_admin_query = "SELECT admin FROM Customer WHERE userName = '" + model.userName + "' AND admin ='true'";
            SqlCommand cmd = new SqlCommand(find_admin_query, conn);
            conn.Open();
            SqlDataReader sdr = cmd.ExecuteReader();
            //it defines admin which is true or false
            model.admin = sdr.HasRows;
            conn.Close();

            //if admin is logged in
            if (model.admin == true) {
                Roles.IsUserInRole(model.userName, "admin"); //Is it right?
                if (DAL.UserIsVaild(model.userName, model.password))
                {
                    FormsAuthentication.SetAuthCookie(model.userName, true);
                    return RedirectToAction("Index", "Product");
                }
            }

            //if customer is logged in
            if (model.admin == false) {
                if (DAL.UserIsVaild(model.userName, model.password))
                {
                    FormsAuthentication.SetAuthCookie(model.userName, true);                   
                    return RedirectToAction("Index", "Home");
                }
            }
                ModelState.AddModelError("", "The user name or password is incorrect.");
        }
        // If we got this far, something failed, redisplay form
        return View(model);
    }

E a classe DAL é

 public class DAL
{
    static SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["rentalDB"].ToString());

    public static bool UserIsVaild(string userName, string password)
    {
        bool authenticated = false;
        string customer_query = string.Format("SELECT * FROM [Customer] WHERE userName = '{0}' AND password = '{1}'", userName, password);      
        SqlCommand cmd = new SqlCommand(customer_query, conn);
        conn.Open();
        SqlDataReader sdr = cmd.ExecuteReader();
        authenticated = sdr.HasRows;
        conn.Close();
        return (authenticated);
    }
}

Finalmente, quero personalizar [Authorize(Roles="admin")]

[Authorize(Roles="admin")]
public class ProductController : Controller
{
  public ViewResult Index()
    {
        var product = db.Product.Include(a => a.Category);
        return View(product.ToList());
    }
}

Este é o meu código-fonte agora.Preciso criar a classe 'AuthorizeAttribute'?Se eu tiver que fazer, como posso fazer isso?Você poderia me explicar?Não consigo entender como definir uma função específica no meu caso.Por favor me ajude como posso fazer.Obrigado.

Foi útil?

Solução

Seu uso de Role.IsInRole não está correto.É para isso que o [Authorize (Roles = "Admin")] é usado, sem necessidade de chamá -lo.

No seu código você não está definindo as funções em lugar nenhum.Se quiser fazer o gerenciamento de funções personalizado, você pode usar seu próprio provedor de funções ou armazená-los no token de autenticação, conforme mostrado aqui:

http://www.codeproject.com/Articles/36836/Forms-Authentication-and-Role-based-Authorizationobserve a seção:


// Get the stored user-data, in this case, user roles
            if (!string.IsNullOrEmpty(ticket.UserData))
            {
                string userData = ticket.UserData;
                string[] roles = userData.Split(',');
                //Roles were put in the UserData property in the authentication ticket
                //while creating it
                HttpContext.Current.User = 
                  new System.Security.Principal.GenericPrincipal(id, roles);
            }
        }


No entanto, uma abordagem mais fácil aqui é usar a associação integrada no asp.net.Crie um novo projeto mvc usando o modelo 'aplicativo de internet' e tudo isso será configurado para você.No visual studio, clique no ícone "configuração asp.net" acima do gerenciador de soluções.Você pode gerenciar funções aqui e atribuir funções.

Outras dicas

Eu sei que esta pergunta é um pouco antiga, mas aqui está como fiz algo semelhante.Criei um atributo de autorização personalizado que usei para verificar se um usuário tinha o acesso de segurança correto:

[System.AttributeUsage(System.AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public sealed class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        // Get the roles from the Controller action decorated with the attribute e.g.
        // [AccessDeniedAuthorize(Roles = MyRoleEnum.UserRole + "," + MyRoleEnum.ReadOnlyRole)]
        var requiredRoles = Roles.Split(Convert.ToChar(","));

        // Get the highest role a user has, from role provider, db lookup, etc.
        // (This depends on your requirements - you could also get all roles for a user and check if they have the correct access)
        var highestUserRole = GetHighestUserSecurityRole();

        // If running locally bypass the check
        if (filterContext.HttpContext.Request.IsLocal) return;

        if (!requiredRoles.Any(highestUserRole.Contains))
        {
            // Redirect to access denied view
            filterContext.Result = new ViewResult { ViewName = "AccessDenied" };
        }
    }
}

Agora decore o Controlador com o atributo personalizado (você também pode decorar ações individuais do Controlador):

[AccessDeniedAuthorize(Roles="user")]
public class ProductController : Controller
{
    [AccessDeniedAuthorize(Roles="admin")]
    public ViewResult Index()
    {
        var product = db.Product.Include(a => a.Category);
        return View(product.ToList());
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top