2014-08-28 3 views
6

Я создал пользовательскую аутентификацию и авторизацию для своих пользователей. Проблема, с которой я столкнулась, заключается в том, как заставить mvc проверять, что роль из таблицы моих пользователей соответствует [Авторизовать (Роль)] на моем контроллере, чтобы настроить httpauthorised на true.Below - мой класс customauthorise.Пользовательская авторизация пользователя, основанная на ролях в asp.net mvc

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] 
public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 
     if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      filterContext.Controller.TempData["ErrorDetails"] = "You must be logged in to access this page"; 
      filterContext.Result = new RedirectResult("~/User/Login"); 
      return; 
     } 

     if (filterContext.HttpContext.Request.IsAuthenticated) 
     { 
      using (var db = new GManagerDBEntities()) 
      { 
       var authorizedRoles = (from u in db.Users 
             where u.Username == filterContext.HttpContext.User.Identity.Name 
             select u.Role).FirstOrDefault(); 
       Roles = String.IsNullOrEmpty(Roles) ? authorizedRoles.ToString() : Roles; 
      } 
     } 

     if (filterContext.Result is HttpUnauthorizedResult) 
     { 
      filterContext.Controller.TempData["ErrorDetails"] = "You do nat have necessary rights to access this page"; 
      filterContext.Result = new RedirectResult("~/User/Login"); 
      return; 
     } 

    } 
    public CustomAuthorizeAttribute(params object[] roles) 
    { 
     if (roles.Any(r => r.GetType().BaseType != typeof(Enum))) 
      throw new ArgumentException("roles"); 

     this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r))); 
    } 
} 

ниже мой контроллер с украшением

[CustomAuthorize(Role.Administrator)] 
    [HttpGet] 
    public ActionResult CreateEmployees() 
    { 
     return View(); 
    } 

и мое перечисление для роли

public enum Role 
{ 
    Administrator = 1, 
    UserWithPrivileges = 2, 
    User = 3, 
} 

и модель

public class UserModel 
{ 
    public int UserID { get; set; } 
    [Required] 
    [Display(Name="Username:")] 
    public string Username { get; set; } 
    [Required] 
    public string Password { get; set; } 
    public int Role { get; set; } 
} 

см Pastie для ясного зрения pastie

ссылки Я просмотрены в попытке решить эту проблему среди других, но я не могу показаться, чтобы собрать вместе MVC 3 Authorize custom roles http://forums.asp.net/p/1573254/3948388.aspx

Customized authorization attribute in MVC 4 with Roles

+1

посмотрите по адресу: //www.codeproject.com/Articles/578374/AplusBeginner-splusTutorialplusonplusCustomplusF –

+0

Я надеюсь использовать одну единственную таблицу и роль как целое, но если все не удастся, просто создаст таблицу ролей и выполнит ваше предложение @VikasRana – GotaloveCode

+0

Я попытался изменить его в соответствии с вашей ссылкой на этот http : //pastie.org/9510205 до сих пор не повезло – GotaloveCode

ответ

4

по ссылке разделяемое @VikasRana http://www.codeproject.com/Articles/578374/AplusBeginner-splusTutorialplusonplusCustomplusF

Я избавилась моего перечисления Роль и мой метод

public CustomAuthorizeAttribute(params object[] roles) 
    { ...} 

I затем изменил роль в моей модели на строку, например. User.Role = "Admin" вместо int. В моем методе onAuthorization я изменил его:

` public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 
     if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      filterContext.Controller.TempData["ErrorDetails"] = "You must be logged in to access this page"; 
      filterContext.Result = new RedirectResult("~/User/Login"); 
      return; 
     } 
     if (filterContext.Result is HttpUnauthorizedResult) 
     { 
      filterContext.Controller.TempData["ErrorDetails"] = "You don't have access rights to this page"; 
      filterContext.Result = new RedirectResult("~/User/Login"); 
      return; 
     } 
     } 

и в моем global.asax добавил это.

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) 
    { 
     if (FormsAuthentication.CookiesSupported == true && Request.IsAuthenticated== true) 
     { 
      if (Request.Cookies[FormsAuthentication.FormsCookieName] != null) 
      { 
       try 
       { 
        //let us take out the username now     
        string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name; 
        string roles = string.Empty; 

        using (GManagerDBEntities db = new GManagerDBEntities()) 
        { 
         User user = db.Users.SingleOrDefault(u => u.Username == username); 

         roles = user.Role; 
        } 
        //let us extract the roles from our own custom cookie 
        //Let us set the Pricipal with our user specific details 
        HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(
         new System.Security.Principal.GenericIdentity(username, "Forms"), roles.Split(';')); 
       } 
       catch (Exception) 
       { 
        //something went wrong 
       } 
      } 
     } 
    } 

Выше метод не идеален, хотя. Он запускается для каждого простого запроса страницы примерно 3 раза или более.

Так вот решение 2: лучшее решение Реализовать пользовательского поставщика роль, так как мы уже используем пользовательскую роль implementation.Simply по этой ссылке http://techbrij.com/custom-roleprovider-authorization-asp-net-mvc

1

Благодаря Gotalove этого метода в Global.asax. Вот еще одна помощь для тех, кто пытается выполнить пользовательскую проверку подлинности на основе форм (FormsAuthentication, FormsAuthenticationTicket), используя инфраструктуру сущности.

Войти Контроллер SetAuthTicket

protected void GetRoles(int UserID) 
    { 
     var db = new ResearchSurveysEntities(); 
     string[] getRoles = { }; 
     try 
     { 
      var query = 

       from p in db.UserProfiles 
       join i in db.webpages_UsersInRoles on p.UserId equals i.UserId 
       join r in db.webpages_Roles on i.RoleId equals r.RoleId 
       where p.UserId == UserID 
       select new { p.UserId, r.RoleName }; 

      if (query.Count() > 0) 
      { 

       List<string> gRoles = new List<string>(); 
       foreach (var item in query) 
       { 
        gRoles.Add(item.RoleName); 
       } 
       getRoles = gRoles.ToArray(); 
      } 
      roles = String.Join("|", getRoles); 
     } 
     catch (Exception ex) 
     { 
      WebUtilities wu = new WebUtilities(); 

      wu.NotifyWebmaster(ex.ToString(), "Get roles for AdminUserID: " + UserID.ToString(), string.Empty, "Login Error"); 


     } 
     finally 
     { 
      db.Dispose(); 
     } 
    } 

WebConfig

<authentication mode="Forms"> 
    <forms loginUrl="~/Account/Login" timeout="2880" /> 
</authentication> 

Global.asax (Из выше примера)

protected void Application_AuthenticateRequest(Object sender, EventArgs e) 
    { 
     HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
     if (authCookie == null || authCookie.Value == "") 
      return; 

     FormsAuthenticationTicket authTicket; 
     try 
     { 
      authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
     } 
     catch 
     { 
      return; 
     } 

     // retrieve roles from UserData 
     string[] roles = authTicket.UserData.Split('|'); 

     if (Context.User != null) 
      Context.User = new GenericPrincipal(Context.User.Identity, roles); 
    } 
Смежные вопросы