本文介绍了使用自定义的IPrincipal和IIdentity的在MVC3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

创建我自己的的IPrincipal 的IIdentity 如下图所示执行:

I create my own IPrincipal and IIdentity implementation as shown below:

[ComVisible(true)]
[Serializable]
public sealed class CustomIdentity : IIdentity {

    private readonly string _name;
    private readonly string _email;
    // and other stuffs

    public CustomIdentity(string name) {
        _name = name.Trim();
        if(string.IsNullOrWhiteSpace(name))
            return;
        _email = (connect to database and read email and other stuffs);
    }

    public string Name {
        get { return _name; }
    }

    public string Email {
        get { return _email; }
    }

    public string AuthenticationType {
        get { return "CustomIdentity"; }
    }

    public bool IsAuthenticated {
        get { return !string.IsNullOrWhiteSpace(_name); }
    }

}


[ComVisible(true)]
[Serializable]
public sealed class CustomPrincipal : IPrincipal {

    private readonly CustomIdentity _identity;

    public CustomPrincipal(CustomIdentity identity) {
        _identity = identity;
    }

    public bool IsInRole(string role) {
        return _identity != null &&
               _identity.IsAuthenticated &&
               !string.IsNullOrWhiteSpace(role) &&
               Roles.IsUserInRole(_identity.Name, role);
    }

    IIdentity IPrincipal.Identity {
        get { return _identity; }
    }

    public CustomIdentity Identity {
        get { return _identity; }
    }

}

另外,我创建了一个的HttpModule ,并在其的AuthenticateRequest 事件,我这样做:

Also, I create a HttpModule and in its AuthenticateRequest event, I do this:

    public void Init(HttpApplication context) {
        _application = context;
        _application.AuthenticateRequest += ApplicationAuthenticateRequest;
    }

    private void ApplicationAuthenticateRequest(object sender, EventArgs e) {
        var formsCookie = _application.Request.Cookies[FormsAuthentication.FormsCookieName];
        var identity = formsCookie != null
             ? new CustomIdentity(FormsAuthentication.Decrypt(formsCookie.Value).Name)
             : new CustomIdentity(string.Empty);
        var principal = new CustomPrincipal(identity);
        _application.Context.User = Thread.CurrentPrincipal = principal;
    }

另外,我创造我自己的控制器 WebViewPage 这样的:

public abstract class CustomController : Controller {
    public new CustomPrincipal User {
        get {
            var user = System.Web.HttpContext.Current.User as CustomPrincipal;
            return user;
        }
    }
}


public abstract class CustomWebViewPage<TModel> : WebViewPage<TModel> {
    public new CustomPrincipal User {
        get {
            // (Place number 1) here is the error I'm speaking about!!!
            var user = HttpContext.Current.User as CustomPrincipal;
            return user;
        }
    }
}

如上面code所示

,似乎一切是正确的;但正如你所看到的,在广场1号我无法访问 CustomPrincipal !意味着在这个地方,我有一个 RolePrincipal ,而不是有一个 CustomPrincipal 。例如 HttpContext.Current.User RolePrincipal 而不是 CustomPrincipal 。但 RolePrincipal.Identity 属性是 CustomIdentity

as shown in above code, it seems everything is right; But as you can see, in Place number 1 I can't access the CustomPrincipal! Means in this place, I have a RolePrincipal instead of having a CustomPrincipal. e.g. HttpContext.Current.User is a RolePrincipal instead of CustomPrincipal. But the RolePrincipal.Identity property is a CustomIdentity!

推荐答案

您的错误是在这里:

_application.AuthenticateRequest += ApplicationAuthenticateRequest;

有一个的HttpModule 名为 RoleManagerModule 调用一个方法 HttpApplication.PostAuthenticateRequest 并设置 HttpContext.Current.User RolePrincipal 。所以,你设置用户的AuthenticateRequest RoleManagerModule 设置它 PostAuthenticateRequest ,你的一套装置之后,因此将覆盖您的设置。更改 Module.Init

There is a HttpModule named RoleManagerModule that invokes a method in HttpApplication.PostAuthenticateRequest and sets the HttpContext.Current.User to RolePrincipal. So, you were setting the User in AuthenticateRequest and the RoleManagerModule sets it in PostAuthenticateRequest, means after your set, so overrides your settings. Change your Module.Init:

public void Init(HttpApplication context) {
    _application = context;
    // change just this line:
    _application.PostAuthenticateRequest += ApplicationAuthenticateRequest;
}

重要更新:

请参阅this问题通过启动-asked再次,依靠目前的问卷的第二个解决办法,如果这一项不工作。

Please see this question -asked by starter again, depended on current question- for a second solution, if this one doesn't work.

这篇关于使用自定义的IPrincipal和IIdentity的在MVC3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-07 12:03