我怎么会模仿User.IsInRole() [英] How would I mimic User.IsInRole()

查看:152
本文介绍了我怎么会模仿User.IsInRole()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网站,多数民众赞成建立与VS 2012的互联网应用程序(简单会员)EF code首先

I have a website thats build with VS 2012 Internet Application ( Simple membership) EF Code First

更新

我想知道如何延长 HttpContext.User.IsInRole(角色)的自定义功能表 - > User.IsInClient (客户端)

I would like to know how to extend HttpContext.User.IsInRole(role) 's functionality for a custom table -> User.IsInClient(client).

推荐答案

下面是我建议来解决您的问题的方式:

Here is the way I'd suggest to solve your issue:

创建您自己的接口,它实现 System.Security.Principal ,在那里你可以把你需要的任何方法:

Create your own interface which implements System.Security.Principal, where you could place any methods you need:

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

实现此接口:

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

的Global.asax.cs 自定义主要分配给请求用户上下文(和可选的执行线程,如果你打算以后使用它)。我建议使用 Application_PostAuthenticateRequest 事件不是 Application_AuthenticateRequest 这个任务,否则你的本金将被覆盖(至少由ASP。 NET MVC 4):

In the Global.asax.cs assign your custom principal to the request user context (and optionally to the executing thread if you plan to use it later). I suggest to use Application_PostAuthenticateRequest event not Application_AuthenticateRequest for this assignment, otherwise your principal will be overridden (at least by 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");
     * }
     */         
}

接下来,为了能够使用在控制器中的属性用户的HttpContext 没有它转换为 ICustomPrincipal 每一次,定义基本控制器,你覆盖默认用户属性:

Next, to be able to use the property User from HttpContext in the controller without casting it to ICustomPrincipal each time, define base controller where you override the default User property:

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

现在,让其他控制器继承它:

Now, let other controllers inherit from it:

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

如果您使用的Razor视图引擎,然后你想成为能够使用方法非常相似的方式上的意见:

If you use Razor View Engine, and you'd like to be able to use your method in the very similar way on the views:

@User.IsInClient(name)

您需要重新定义 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; }
    }
}

和告诉剃刀以反映变化,通过修改意见的相应部分\\ Web.config文件文件:

and tell Razor to reflect you changes, by modifying appropriate section of the Views\Web.config file:

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

这篇关于我怎么会模仿User.IsInRole()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆