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">
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 ..? –
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
@JaroslawWaliszko Zaktualizowano pytanie, które sprawia, że coraz więcej osób zadaje to w ten sposób. –