2013-08-21 41 views
6

Tôi có một trang web thats xây dựng với VS 2012 ứng dụng Internet (thành viên Simple) EF Mã Đầu tiênLàm thế nào tôi có thể bắt chước User.IsInRole()

cập nhật

tôi muốn biết làm thế nào để mở rộng chức năng của HttpContext.User.IsInRole(role) cho một bảng tùy chỉnh ->User.IsInClient(client).

+0

bump .... Cách tạo Lớp mới có chức năng này có thể? Sau đó, để có thể gọi lớp học từ View hoặc Controller khi cần ..? –

+2

Bạn có thể giải thích nó tốt hơn không? 'Users.InRoles (" Admin ")' là gì? nó có thể được tìm thấy ở đâu? Là nó bên trong khuôn khổ hoặc là nó tùy chỉnh của bạn? Có lẽ bạn đang hỏi về 'HttpContext.User.IsInRole (vai trò) 'và một cách để mở rộng chức năng này cho' HttpContext.User.IsInClient (client) 'thay thế? – jwaliszko

+0

@JaroslawWaliszko Đã cập nhật câu hỏi, điều đó khiến cho nhiều người hơn phải hỏi theo cách này. –

Trả lời

14

Dưới đây là cách tôi muốn đề nghị để giải quyết vấn đề của bạn:

Tạo giao diện riêng của bạn mà thực hiện System.Security.Principal, nơi bạn có thể đặt bất kỳ phương pháp bạn cần:

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

Thực hiện giao diện này:

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

Trong Global.asax.cs gán hiệu trưởng tùy chỉnh của bạn cho người dùng yêu cầu ext (và tùy chọn cho chuỗi thực hiện nếu bạn dự định sử dụng nó sau này). Tôi đề nghị để sử dụng Application_PostAuthenticateRequest sự kiện không Application_AuthenticateRequest cho nhiệm vụ này, nếu không chính bạn sẽ được ghi đè (ít nhất là bằng 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"); 
    * } 
    */   
} 

Tiếp theo, để có thể sử dụng thuộc tính User từ HttpContext trong điều khiển mà không cần đúc nó để ICustomPrincipal mỗi lần, xác định bộ điều khiển cơ sở nơi bạn ghi đè mặc định User tài sản:

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

Bây giờ, hãy điều khiển khác kế thừa từ nó:

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

Nếu bạn sử dụng Razor View Engine, và bạn muốn để có thể sử dụng phương pháp của bạn theo cách rất giống nhau về quan điểm:

@User.IsInClient(name) 

bạn cần phải xác định lại loại WebViewPage:

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

và nói với Razor để phản ánh bạn thay đổi, bằng cách thay đổi phần thích hợp của Views \ Web.config file:

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

WebviewPage lớp chỉ là bất kỳ lớp học ngẫu nhiên hoặc làm thế nào tôi nên xác định nó? –

+2

@Don Thomas Boyle: 'WebViewPage' là lớp khung hợp pháp từ không gian tên' System.Web.Mvc'. – jwaliszko

+1

Được rồi, vậy chúng tôi chỉ ghi đè Lớp WebViewPage đã tồn tại nhưng không thể xem được? –

0

Sử dụng 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

không phải là 2 lần tham gia vì chúng tôi có 3 bảng? 'Users'' Clients' 'UserInCleints' (chứa 2 id của' User' và 'Client'). Nhưng member.getallusers() là neet. Tôi thích khái niệm này cho đến nay –

+0

@DonThomasBoyle nếu bạn có bảng UserInCleints bạn có thể tham gia nó thay vì bảng Người dùng. –

+0

Vâng, nhưng điều đó chỉ mang lại cho tôi Id của trở lại, tôi sẽ muốn các tên và các thông tin khác liên quan đến những id của. –

-1

thử cách này

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

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

Tôi nghĩ rằng bạn hiểu sai, tôi đang cố gắng tạo lại phương thức InRoles cho InClients cho 2 mô hình và phương thức rất riêng biệt, không có người trợ giúp hoặc lớp học nào cho việc này. –

-2

Thủ tục lưu trữ sẽ được tốt hơn trong trường hợp này.

+1

xin lỗi nhưng điều đó không có ý nghĩa gì cả -1. –