Frage

Ich habe eine MVC-app, wo ich eine User-Klasse haben und der Benutzer kann auch einen anderen Benutzer (Admin-Benutzer) ausgeben.

Also ich habe diesen Code unten, dass authentisiert die Anfrage und instanziiert meine Version eines Benutzerklasse.

Es versucht dann, den imitierten Benutzer aus dem Session-Objekt zu erhalten, aber Session ist in diesem Verfahren in dem global.asax nicht zur Verfügung.

Hope dies Sinn macht.

Wie sonst könnte ich das tun?

Meine Frage, die ich Vermutung ist, an welcher Stelle in den global.asax Methoden tun erhalten Sie Zugriff auf Session-Objekt für jede Anforderung?

protected void Application_OnAuthenticateRequest(object sender, EventArgs e)
{
    IMylesterService service = ObjectFactory.GetInstance<IMylesterService>();

    if (Context.User != null)
    {
        if (Context.User.Identity.IsAuthenticated)
        {
            User user = service.GetUser(Context.User.Identity.Name);
            if (user == null)
                throw new ApplicationException("Context.user.Identity.name is not a recognized user");

            User impersonatedUser = (User)this.Session["ImpersonatedUser"];
            if (impersonatedUser == null)
                user.ImpersonatedUser = user;
            else
                user.ImpersonatedUser = impersonatedUser;

            System.Threading.Thread.CurrentPrincipal = Context.User = user;
            return;
        }
    }
    User guest = service.GetGuestUser();
    guest.ImpersonatedUser = guest;

    System.Threading.Thread.CurrentPrincipal = Context.User = guest;
}

Keine korrekte Lösung

Andere Tipps

Versuchen

einen Berechtigungsfilter erstellen:

public class CustomAuthorizationFilter : AuthorizeAttribute
{
    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        // perform your authorization here
        // full access to HttpContext and session
    }
}

Sie können dann dieses Attribut auf Ihre Controller anwenden. Im Idealfall würden Sie einen Basis-Controller haben, dass alle anderen Controller erben von und man konnte das Attribut auf Klassenebene auf diesem Controller anwenden. Dann werden alle Ihre Anfragen genehmigt werden würde und die Identitätswechsel anwenden, wie Sie oben codiert haben.

Session wird während AuthenticateRequest nicht verfügbar sein: Was Sie tun müssen, um Tag ist die erforderliche Information des Identity.userData; so zum Beispiel, wenn Sie, wo Formulare mit Authentifizierung wie folgt vor:

void Application_AuthenticateRequest(object sender, EventArgs e)
{
   if (Context.User != null)
   {
     if (Context.User.Identity.IsAuthenticated)
     {
       // retrieve the value 
       var id = (FormsIdentity)Context.User.Identity;
       var myvalue = id.Ticket.UserData; // "Here you are"
     }
   }
}

Zeichen in Formen verwenden, müssen Sie eine benutzerdefinierte Cookie schreiben: MVC -> Klasse FormsAuthenticationService: IFormsAuthenticationService

public static void SetAuthenticationCookie(HttpContextBase context, FormsAuthenticationTicket ticket)
{
    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName)
       {
          Value = FormsAuthentication.Encrypt(ticket),
          Secure = FormsAuthentication.RequireSSL,
          Domain = FormsAuthentication.CookieDomain,
          HttpOnly = true,
          Expires = DateTime.Now.AddMinutes(15)
       };

    if (!context.Request.IsSecureConnection && FormsAuthentication.RequireSSL)
    {
        throw new HttpException("Ticket requires SSL.");
    }
    context.Response.Cookies.Add(cookie);
}
public static FormsAuthenticationTicket CreateTicket(HttpContextBase context, string emailAddress, string userData, bool persist)
{
    return new FormsAuthenticationTicket(1, emailAddress, DateTime.Now, DateTime.Now.AddMinutes(15), persist, userData, FormsAuthentication.FormsCookiePath);
}

Schließlich in SignIn würden Sie nun das gewünschte Ticket erstellen, indem CreateTicket Aufruf (...), und dann würden Sie es durch SetAuthenticationCookie schreiben (...).

public void SignIn(string userName, string password)
{
    if(CheckUserValid(userName,password, out string email))
    {
        var ticket = CreateTicket(email, "Here you are", true);
        SetAuthenticationCookie(HttpContext.Current.Base(), ticket);
    }
}

Ich habe es nie benutzt, aber davon ausgehen, dass Sitzungszustand während des AcquireRequestState zugeordnet:

public void Init(HttpApplication context)
{
    context.AcquireRequestState += new EventHandler(context_AcquireRequestState);
}

hatte ich das gleiche Problem in global.asax zu Zugriffssitzung des Müssens und löste es schließlich durch meinen Code in den AcquireRequestState Handler bewegt, die geschehen, nachdem die Authentifizierung übergeben wird.

    protected void Application_AcquireRequestState(Object sender, EventArgs e)
    {
        if (Request.IsAuthenticated && Context.Session != null)
        {
            // access Context.Session
        }
    }

Das Feuer viel und der aktuelle Kontext immer kein gültiges Session-Objekt hat, damit die Kontrolle.

Bearbeiten : Hat die Prüfung für IsAuthenticated auch addieren - wurden einen Null-Fehler bekommen, wenn abgemeldet. Funktioniert prima jetzt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top