2013-08-21 25 views
6

Mam internetowej ów budować z VS 2012 Internet Application (Simple członkostwa) EF kod najpierwJak chciałbym naśladować User.IsInRole()

Aktualizacje

chciałbym wiedzieć jak rozszerzyć funkcjonalność HttpContext.User.IsInRole(role) dla niestandardowej tabeli ->User.IsInClient(client).

+0

bump .... Sposób na stworzenie nowej klasy, która może tę funkcję? Następnie, aby w razie potrzeby móc wywołać klasę z widoku lub kontrolera ..? –

+2

Czy możesz to lepiej wyjaśnić? Co to jest "Users.InRoles (" Admin ")'? Gdzie można go znaleźć? Czy to jest wewnątrz frameworka czy jest to twoja niestandardowa rzecz? Może pytasz o 'HttpContext.User.IsInRole (rola) 'i sposób na rozszerzenie tej funkcji do' HttpContext.User.IsInClient (client) 'zamiast? – jwaliszko

+0

@JaroslawWaliszko Zaktualizowano pytanie, które sprawia, że ​​coraz więcej osób zadaje to w ten sposób. –

Odpowiedz

14

Oto sposób sugeruję, aby rozwiązać swój problem:

Stwórz swój własny interfejs, który implementuje System.Security.Principal, gdzie można umieszczać żadnych metod, których potrzebujesz:

public interface ICustomPrincipal : IPrincipal 
{ 
    bool IsInClient(string client); 
} 

Wdrożenie tego interfejsu:

public class CustomPrincipal : ICustomPrincipal 
{ 
    private readonly IPrincipal _principal; 

    public CustomPrincipal(IPrincipal principal) { _principal = principal; } 

    public IIdentity Identity { get { return _principal.Identity; } } 
    public bool IsInRole(string role) { return _principal.IsInRole(role); } 

    public bool IsInClient(string client) 
    { 
     return _principal.Identity.IsAuthenticated 
       && GetClientsForUser(_principal.Identity.Name).Contains(client); 
    } 

    private IEnumerable<string> GetClientsForUser(string username) 
    { 
     using (var db = new YourContext()) 
     { 
      var user = db.Users.SingleOrDefault(x => x.Name == username); 
      return user != null 
         ? user.Clients.Select(x => x.Name).ToArray() 
         : new string[0]; 
     } 
    } 
} 

W Global.asax.cs przypisać swój własny kapitał na żądanie użytkownika cd ext (i opcjonalnie do wątku wykonawczego, jeśli planujesz użyć go później). Proponuję użyć Application_PostAuthenticateRequest zdarzenie nie Application_AuthenticateRequest dla tego zadania, w przeciwnym razie główny zostaną nadpisane (przynajmniej przez ASP.NET MVC 4):

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) 
{ 
    Context.User = Thread.CurrentPrincipal = new CustomPrincipal(User); 

    /* 
    * BTW: Here you could deserialize information you've stored earlier in the 
    * cookie of authenticated user. It would be helpful if you'd like to avoid 
    * redundant database queries, for some user-constant information, like roles 
    * or (in your case) user related clients. Just sample code: 
    * 
    * var authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; 
    * var authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
    * var cookieData = serializer.Deserialize<CookieData>(authCookie.UserData); 
    * 
    * Next, pass some deserialized data to your principal: 
    * 
    * Context.User = new CustomPrincipal(User, cookieData.clients); 
    * 
    * Obviously such data have to be available in the cookie. It should be stored 
    * there after you've successfully authenticated, e.g. in your logon action: 
    * 
    * if (Membership.ValidateUser(user, password)) 
    * { 
    *  var cookieData = new CookieData{...};   
    *  var userData = serializer.Serialize(cookieData); 
    * 
    *  var authTicket = new FormsAuthenticationTicket(
    *   1, 
    *   email, 
    *   DateTime.Now, 
    *   DateTime.Now.AddMinutes(15), 
    *   false, 
    *   userData); 
    * 
    *  var authTicket = FormsAuthentication.Encrypt(authTicket); 
    *  var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, 
              authTicket); 
    *  Response.Cookies.Add(authCookie); 
    *  return RedirectToAction("Index", "Home"); 
    * } 
    */   
} 

Następny, aby móc skorzystać z właściwości User z HttpContext w regulator bez rzucania go ICustomPrincipal za każdym razem, zdefiniować podstawowy kontroler gdzie zastąpić właściwość domyślna User:

public class BaseController : Controller 
{ 
    protected virtual new ICustomPrincipal User 
    { 
     get { return (ICustomPrincipal)base.User; } 
    } 
} 

teraz inne kontrolery dziedziczyć po nim:

public class HomeController : BaseController 
{ 
    public ActionResult Index() 
    { 
     var x = User.IsInClient(name); 

Jeśli używasz Razor Zobacz Silnik, i chcesz, aby móc korzystać z metody w bardzo podobny sposób na widokach:

@User.IsInClient(name) 

trzeba przedefiniować WebViewPage Typ:

public abstract class BaseViewPage : WebViewPage 
{ 
    public virtual new ICustomPrincipal User 
    { 
     get { return (ICustomPrincipal)base.User; } 
    } 
} 

public abstract class BaseViewPage<TModel> : WebViewPage<TModel> 
{ 
    public virtual new ICustomPrincipal User 
    { 
     get { return (ICustomPrincipal)base.User; } 
    } 
} 

i powiedzieć Ci Razor odzwierciedlać zmiany, modyfikując odpowiedni dział Wyświetleń \ Web.config pliku:

<system.web.webPages.razor> 
    ... 
    <pages pageBaseType="YourNamespace.BaseViewPage"> 
+0

Klasa WebviewPage jest po prostu dowolną klasą losową lub jak powinienem ją zdefiniować? –

+2

@Don Thomas Boyle: 'WebViewPage' jest uprawnioną klasą szkieletową z przestrzeni nazw' System.Web.Mvc'. – jwaliszko

+1

Dobra, więc właśnie przesłonimy już istniejącą, ale niewidoczną klasę WebViewPage? –

0

używać LINQ:

var Users = Membership.GetAllUsers(); 

//**Kinda Like Users.InCLients(userName). 
var users = from x in Users 
       join y in db.Clinets on x.ProviderUserKey equals y.UserID 
       select x 

//**Kinda Like Clients.InUsers(userName) 
var clients = from x in db.Clinets 
       join y in Users on x.UserID equals y.ProviderUserKey 
       select x 
+0

Czy nie byłoby 2 sprzężeń, ponieważ mamy 3 tabele? 'Użytkownicy'' Klienci' 'UserInCleints' (przechowuje 2 identyfikatory użytkownika' Użytkownik' i 'Klienta'). Ale membership.getallusers() jest neet. Podoba mi się dotychczasowa koncepcja –

+0

@DonThomasBoyle, jeśli masz tabelę UserInCleints, możesz dołączyć do niej zamiast tabeli Użytkownicy. –

+0

Tak, ale to tylko daje mi powrót Id, chciałbym Nazwy i inne informacje związane z tymi id. –

-1

spróbować w ten sposób

List<Clinets> AllClinets =entityObject.Clinets .ToList(); 

Foreach(var check in AllClinets) 
{ 
    if(check.UserTable.RoleTable.RoleName=="Rolename1") 
    { 
     //This users are Rolename1 
    } 
    else 
    { 
    //other. 
    } 
} 
+0

Myślę, że źle zrozumiałeś, próbuję odtworzyć metodę InRoles dla InClients na 2 bardzo oddzielne modele i metody, nie ma w tym celu żadnych pomocników ani klas. –

-2

Procedura składowana byłoby lepiej w tym przypadku.

+1

Przepraszam, ale to nie ma sensu -1. –