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">
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 ..? –
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
@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. –