سؤال

لدي تطبيق MVC حيث لدي فئة مستخدم ويمكن للمستخدم أيضًا انتحال شخصية مستخدم آخر (مستخدمي المسؤول فقط).

لذلك لدي هذا الرمز أدناه الذي يصادق الطلب ويستند إلى الإصدار الخاص بي من فئة المستخدم.

ثم يحاول الحصول على المستخدم المنتحل من كائن الجلسة ولكن الجلسة غير متوفرة في هذه الطريقة في Global.asax.

أتمنى أن يكون هذا منطقيًا.

كيف يمكنني فعل هذا؟

سؤالي أعتقد أنه في أي نقطة في أساليب Global.asax هل يمكنك الوصول إلى كائن الجلسة لكل طلب؟

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

لا يوجد حل صحيح

نصائح أخرى

حاول إنشاء مرشح تفويض:

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

يمكنك بعد ذلك تطبيق هذه السمة على وحدات التحكم الخاصة بك. من الناحية المثالية ، سيكون لديك وحدة تحكم قاعدة ترثها جميع وحدات التحكم الأخرى ويمكنك تطبيق السمة على مستوى الفصل على وحدة التحكم هذه. بعد ذلك ، سيتم تصريح جميع طلباتك وتطبيق انتحال شخصية كما قمت بترميزها أعلاه.

لن تكون الجلسة متاحة أثناء AuthenticatereQuest: ما ستحتاج إلى فعله هو وضع علامة على المعلومات المطلوبة على الهوية. userdata ؛ لذلك على سبيل المثال ، إذا كنت تستخدم مصادقة النماذج ، افعل ما يلي:

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

لتسجيل الدخول باستخدام النماذج ، ستحتاج إلى كتابة ملف تعريف ارتباط مخصص: MVC -> فئة الدرجة

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

أخيرًا ، في تسجيل الدخول ، يمكنك الآن إنشاء التذكرة المطلوبة عن طريق الاتصال CreateTicket (...) ، وبعد ذلك ستكتبها بواسطة setAuthenticationCookie (...).

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

لم أستخدمها مطلقًا ، لكنني أفترض أن حالة الجلسة تم تعيينها أثناء CustireRequestState:

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

لقد واجهت نفس القضية المتمثلة في الوصول إلى الجلسة في Global.asax وأخيراً حلها عن طريق تحريك الكود الخاص بي إلى AcquireRequestState المعالج ، الذي يحدث بعد تمرير المصادقة.

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

هذا يطلق النار كثيرًا ولا يحتوي السياق الحالي دائمًا على كائن جلسة صالح ، وبالتالي الشيك.

تعديل: اضطررت إلى إضافة الشيك لـ isauthenticated أيضًا - كان الحصول على خطأ فارغ عند تسجيل الخروج. يعمل بشكل رائع الآن.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top