2014-08-28 28 views
6

Ho creato un'autenticazione e un'autorizzazione personalizzate per i miei utenti. Il problema che sto affrontando è come ottenere che mvc verifichi che il ruolo dalla tabella degli utenti corrisponda a [Autorizza (Ruolo)] sul mio controller in modo da impostare httpauthorised su true.Below è la mia classe customauthorise.Autorizzazione utente personalizzata in base ai ruoli in 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))); 
    } 
} 

sotto è il mio controller con decorazione

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

e il mio enum per il ruolo

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

e il modello

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

vedere pastie per visione chiara pastie

link ho visto nel tentativo di risolvere questo tra gli altri, ma i cant sembrano piece insieme MVC 3 Authorize custom roles http://forums.asp.net/p/1573254/3948388.aspx

Customized authorization attribute in MVC 4 with Roles

+1

dare un'occhiata a http: //www.codeproject.it/Articoli/578374/AplusBeginner-splusTutorialplusonplusCustomplusF –

+0

Spero di utilizzare una singola tabella e un ruolo come numero intero ma se tutto fallisce creerò solo una tabella dei ruoli e implementerò il tuo suggerimento @VikasRana – GotaloveCode

+0

Ho provato a cambiarlo in base al tuo link a questo http : //pastie.org/9510205 ancora senza fortuna – GotaloveCode

risposta

4

utilizzando il link condiviso da @VikasRana http://www.codeproject.com/Articles/578374/AplusBeginner-splusTutorialplusonplusCustomplusF

mi sono liberato del mio enum Ruolo e metodo

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

I quindi ho cambiato ruolo nel mio modello in modo che fosse una stringa, ad es. User.Role = "Admin" invece di int. Nel mio metodo onAuthorization ho cambiato in:

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

e nel mio global.asax aggiunte questo.

Sopra il metodo non è l'ideale però.Esso viene eseguito per ogni richiesta di pagina semplice circa 3 volte o più.

ecco Soluzione 2: soluzione migliore Implementare un provider di ruoli personalizzato dato che stiamo già utilizzando ruolo personalizzato implementation.Simply segui questo link http://techbrij.com/custom-roleprovider-authorization-asp-net-mvc

1

Grazie Gotalove per questo metodo in Global.asax. Ecco un ulteriore aiuto per chiunque cerchi di eseguire un'autenticazione basata su form personalizzata (FormsAuthentication, FormsAuthenticationTicket) utilizzando il framework di entità.

Accesso controller 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 (Dall'alto esempio)

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