17

ich meine eigene IPrincipal und IIdentity Implementierung erstellen, wie unten dargestellt:mit benutzerdefinierten IPrincipal und IIdentity in MVC3

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

} 

Auch erstelle ich ein HttpModule und in seinem AuthenticateRequest Ereignisse, das tue ich dies:

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

Außerdem erstelle ich meine eigene Controller und WebViewPage wie diese:

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

wie in obigem Code gezeigt, scheint es, dass alles richtig ist; Aber wie Sie sehen können, in Platz Nummer 1 Ich kann nicht auf die CustomPrincipal zugreifen! Bedeutet an diesem Ort, ich habe eine RolePrincipal anstelle einer CustomPrincipal. z.B. HttpContext.Current.User ist ein RolePrincipal anstelle von CustomPrincipal. Aber die RolePrincipal.Identity Eigenschaft ist eine CustomIdentity!

Antwort

19

Ihr Fehler ist hier:

_application.AuthenticateRequest += ApplicationAuthenticateRequest; 

Es gibt eine HttpModule benannt ist RoleManagerModule, das ein Verfahren in HttpApplication.PostAuthenticateRequest aufruft und setzt den HttpContext.Current.User-RolePrincipal. Also, Sie haben die User in AuthenticateRequest eingestellt und die RoleManagerModule setzt es in PostAuthenticateRequest, bedeutet nach Ihrem Set, also überschreibt Ihre Einstellungen. Ändern Sie Ihre Module.Init:

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

WICHTIG UPDATE:

Bitte sehen this question -asked von Starter wieder, hing von aktuellen Frage- für eine zweite Lösung, wenn dieser nicht funktioniert.

+0

Es funktioniert! Danke vielmals. –

+0

Danke für diese Antwort; Ich zog mir die Haare aus, um mir diesen zu überlegen! –

+0

@DavidKeaveny Danke, aber ich muss Ihnen sagen, dass die Lösung ein Problem hat. Wenn Sie in 'king.net's Fragen suchen, können Sie ein Q finden, das in diesem Zusammenhang steht, dass es ein anderes Problem mit IIS gibt, also schlage ich eine Möglichkeit vor, die das Problem gut löst. Bitte schau dir 'king.net's Fragen an, du wirst es finden. Grüße. –