2015-12-02 23 views
12

Bunu saatlerce vuruyorum ve güldüm. Belirli bir önceden tanımlanmış "süper" kullanıcısını otomatik olarak oturum açma girişiminde MVC 5 denetleyicisine ajax posta isteği yapıyorum. Denetleyici yönteminde, HttpContext.Current.User ve kimlik doğrulamasını program aracılığıyla ayarlamaya çalışıyorum, bu nedenle süper kullanıcı el ile oturum açma işlemini atlayabilir. Buradaki fikir birliği burada uygulanmış gibi görünüyor:.net Formlar Kimlik Doğrulaması - HttpContext.Current.User öğesinin özel olarak ayarlanması, özel olarak çalışmaz. AuthorizeAttribute

setting HttpContext.Current.User

Bu, özel bir AuthorizeAttribute ile başka bir denetleyici yöntemlerini görüntülemeye çalışana kadar çalışır gibi görünüyor.

Kontrolör yöntemi: service.Login yöntemi yukarıdaki çerez oluşturur

[HttpPost] 
[AllowAnonymous] 
public ActionResult Login(string username) 
{ 
    string password = ConfigurationManager.AppSettings["Pass"]; 

    User user = service.Login(username, password); 

    var name = FormsAuthentication.FormsCookieName; 
    var cookie = Response.Cookies[name]; 
    if (cookie != null) 
    { 
     var ticket = FormsAuthentication.Decrypt(cookie.Value); 
     if (ticket != null && !ticket.Expired) 
     { 
      string[] roles = (ticket.UserData as string ?? "").Split(','); 
      System.Web.HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), roles); 
     } 
    } 

    //...processing result 

    return Json(result); 
} 

: Ben bir kimlik Kullanıcı, ayarlıyorum ve IsAuthenticated, filterContext doğru olmakla beraber

FormsAuthentication.SetAuthCookie(cookieValue, false); 

.HttpContext.User aşağıda aynı kullanıcı değil. Asla tahsis edilmediyse ve kimliği doğrulanmamış gibi aslında boş. Bulabildiğim

public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    string[] userDetails = filterContext.HttpContext.User.Identity.Name.Split(char.Parse("|")); 
} 

en yakın sonrası buradadır: IsAuthenticated works on browser - but not with Air client!

Ancak bunun için düzeltme Benim için zaten mevcuttu: Ben AuthorizationContext yapmaya ne eksik

<authentication mode="Forms"> 
    <forms cookieless="UseCookies" timeout="60" loginUrl="~/Account/Login" /> 
</authentication> 

. Kullanıcı denetleyicide kimlik doğrulaması yaptığım HttpContext.Current.User ile eşleşiyor?

GÜNCELLEME: Ben düzgün çerez ayarlamak için bir yönlendirme ihtiyacım gerçekleştirmek

, ben bir ajax çağrı yoluyla uzaktan bu işi yapmak için sadece mümkün değilim. Burada, site A'daki komut dosyası, site üzerindeki denetleyici yöntemini çalıştırırken neye benzediğini gösterir. Bu yönlendirme, oturumu başlatmaz. Kullanıcıyı bir sonraki denetleyici yönteminde doğrularken hala mevcut değil. Sadece giriş görünümüne geri yönlendiriyor. bu noktada böylece HttpContext -

function remoteLogin(id) { 
    $.ajax({ 
     url: "/MyController/RemoteLogin", 
     type: "POST", 
     dataType: "json", 
     data: { "id": id } 
    }).done(function (data) { 
     if (data) { 
      if (data.user) { 
       var user = data.user; 
       $.ajax({ 
        url: "http://siteB.xyz/Account/Login", 
        type: "POST", 
        dataType: "json", 
        data: { "username": user.username, "password": user.password } 
       }).done(function (data) { 
        if (data) { 
         window.location.href = "http://siteB.xyz/Next" 
        } else { 
         alert("Fail."); 
        } 
       }).fail(function (data) { 
        alert("Fail."); 
       }); 
      } else { 
       alert("Fail."); 
      } 
     } 
    }).fail(function (data) { 
     alert("Fail."); 
    }); 
} 

cevap

3

sahip sorun yalnızca kimlik doğrulama tanımlama, yeni bir istek kalmayıncaya kadar olmayacak form kimlik doğrulama modülü içinde oluşturulan alır IPrincipal kuruyorsun bu noktada .Kullanıcı garip bir durumda. Yönlendirme gerçekleştiğinde, tarayıcıdan gelen yeni bir istek olduğu için, sayfanıza ulaşılmadan önce çerez kullanıcı tarafından okunacak ve doğru kullanıcı nesnesi oluşturulacaktır.

Çerezler, yalnızca bir istek tamamlandıktan sonra tarayıcıda ayarlanır.

+0

Kendimi bulduğum, etrafa baktığım şey - baktığım şey, denediğim bağlamda bunu yapmak için bir yol - uzak bir giriş. Örneğin, betiğimde "location.href" değerini başarılı olarak ayarlamak fark yaratmaz. Bir ajax çağrısı aracılığıyla, uzaktan tarif etmek istediğinizi yapmanın bir yoluna ihtiyacım var. –

+0

Onaylandı! Ne yaptım (ve bu kesinlikle güvenli), App A tarafında kullanıcı adı/şifre ile bir çerez yazmak, daha sonra ajax çağrı başarısı üzerine, komut dosyasından yeni bir pencere açmak. App B'de geçici çerezleri okuyup yokediyorum, girişi gerçekleştirdim, ardından doğrulanmış görünüme yönlendiriyorum. Her şey işe yarıyor gibi görünüyor. Daha sonra OP'imi detayları ile günceller. –

2

Sorun, işlem kodunuzun istek işleme hattına göre çalıştığı yer ile ilgilidir. Kodunuz ProcessRequest adımında çalışıyor (aşağıya bakın).

HttpContext.Current.User

AuthenticateRequest olay işleyicisi tarafından ayarlanacak bekleniyor. FormsAuthenticationModule, bununla ilgilenir ve İsteği'ni döndürür.Tanımlama Bilgileri ' FormsAuthenticationCookie bir FormsAuthenticationTicket içine ve daha sonra bir IPrincipal içine. Yani asıl Request.CurrentUser olarak ayarlanmış olur ve ben Thread.CurrentPrincipal Bu istek önbellek her zaman kullanıcı ( ResolveRequestCache) ve oturum devlet tarafından değişebilir çünkü AuthenticateRequest adımda yapılması gereken

inanıyoruz (AcquireRequestState) yapar. Ayrıca, AuthorizeRequest adım AuthenticateRequest adımda belirlenen kullanıcı asıl bir 401 veya 300 düzeyli bir giriş sayfasına yönlendirir almadan AuthorizeRequest adımdan geçen için gerekli izne sahip olmadığı hakkında kararlar (ve inanıyorum MVC ve WebAPI en Yetkilendirme mekanizmaları parçası ProcessRequest)

  • BeginRequest
  • AuthenticateRequest (FormsAuthenticationModule)
  • Otoriteler olarak çalışmak zeRequest (örneğin UrlAuthorizationModule)
  • ResolveRequestCache
  • MapRequestHandler
  • AcquireRequestState
  • PreRequestHandlerExecute
  • ProcessRequest (HttpHandler, Web Formları, MVC denetleyicisi eylemleri burada yaşayan)

Bu zorlamayı deneyebilirsiniz HttpContext.Current.UserveayarlanarakThread.CurrentPrincipal , IPrincipal, ancak yalnızca ProcessRequest aşamasında bu noktadan sonra çalışan kod için geçerli olacak ... oturum durumu, önbellek ve yetkilendirme hakkında önemli kararlar zaten yapıldı. Teoride

, size AuthenticateRequest (veya global.asax) HttpModule'ü yazma ve önce/o uygulayarak yapmaya çalıştığımız ne benzer bir şey uygulamak olabilir, ancak henüz daha yüksek erişim olmazdı seviye MVC denetleyici kavramları, Oturum durumu, vb HttpContext.Request.QueryString, HttpContext.Request.Form ve HttpContext.Request.Cookies, ama çok başka incelemek mümkün olurdu. HTTP isteği dışında AJAX çağrısından kullanıcı adı kapmak zorunda ve ya çağrı FormsAuthentication.SetAuthCookie() veya kendine bir FormsAuthenticationTicket ve FormsAuthenticationCookie oluşturmak ve Request.Cookies yılında çerez şeyler ediyorum ve Response.Cookies. Denetleyici mantığınız çalıştığında, isteğin doğrulanmış görüneceğinden eminim.

+0

@ scott732 - Derinlemesine yanıtı gerçekten takdir edin. Sonunda gittiğimden daha karmaşık bir yaklaşıma benziyor. Bu bilmeniz gereken her şey, teşekkürler. –

İlgili konular