2012-03-11 133 views
3

我是新的MVC 3用户,我试图通过SQL数据库进行管理。 首先,我有客户实体和管理员可以通过在客户实体中为布尔类型的管理域来定义。 我只想在产品页面访问管理员,而不是普通客户。 我想让[Authorize(Roles =“admin”)]而不是[Authorize]。 但是,我不知道如何在我的代码中真正实现管理角色。 然后在我的HomeController中,我编写了这段代码。MVC 3授权自定义角色

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); 
    } 

和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); 
    } 
} 

最后,我想进行自定义[授权(角色= “管理员”)

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

这是现在我的源代码。我是否需要制作'AuthorizeAttribute'类? 如果我必须这样做,我该怎么做呢?你能向我解释一下吗?我无法理解如何在我的情况下设置特定角色。 请帮我,我该怎么办。谢谢。

+1

你的代码很容易打开sql注入:String find_admin_query =“SELECT admin FROM Customer WHERE userName ='”+ model.userName +“'AND admin ='true'”; 如果用户名是:';从用户删除; - – 2012-03-11 23:11:15

回答

1

您的Role.IsInRole用法不正​​确。那是什么 [Authorize(Roles =“Admin”)]用于,不需要调用它。

在您的代码中,您并未在任何地方设置角色。如果你想要做自定义角色的管理,你可以使用自己的角色提供或将它们存储在身份验证令牌如下所示:

http://www.codeproject.com/Articles/36836/Forms-Authentication-and-Role-based-Authorization 注意部分:

 

// 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); 
      } 
     } 
 

但是这里一个更简单的方法是使用asp.net中的内置成员资格。 使用“互联网应用程序”模板创建一个新的mvc项目,这将全部为您设置。在Visual Studio中,单击解决方案资源管理器上方的“asp.net配置”图标。您可以在此管理角色并分配给角色。

2

我知道这个问题有点老,但这里是我做了类似的事情。我创建了我用来检查用户是否有正确的安全访问的自定义授权属性:

[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" }; 
     } 
    } 
} 

现在装饰与自定义属性的控制器(也可以装点各个控制器的动作):

[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()); 
    } 
}