2008-10-08 19 views
7

Używam atrybutu uwierzytelniania w niektórych moich działaniach na stronie mvc asp.net, aby odsyłać użytkowników do ekranu logowania, jeśli nie zostali uwierzytelnieni. Moim problemem jest zwrócenie ich na stronę odsyłającą po zalogowaniu. Po prostu śledziłem akcję odsyłającą i odnoszę się do kontrolera, ale to staje się problematyczne, gdy muszę również śledzić niektóre parametry. Czy jest jakiś fajny sztuczka, o której nie wiem?Powrót do strony z odnośnikami

Odpowiedz

3

W przypadku używasz FormsAuthentication, gdy ASP.NET przekierowuje użytkownika na stronę logowania, URL wygląda mniej więcej tak:

http://www.mysite.com/Login?ReturnUrl=/Something 

Atrybut działania formularza logowania powinien mieć ten sam parametr ReturnUrl (jako wejście ukryte lub jako część adresu URL), aby FormsAuthentication mogło go odebrać i przekierować, np.

<form action="Login?ReturnUrl=<%=Html.AttributeEncode(Request.QueryString["ReturnUrl"]) %>"></form> 

lub

<form><input type="hidden" name="ReturnUrl" id="ReturnUrl" value="<%=Html.AttributeEncode(Request.QueryString["ReturnUrl"])"%> /></form> 
2

To, co zrobiłem, aby osiągnąć ten wynik, może być przesadzone, i chciałbym zobaczyć również inne metody. Jednak oto mój kod.

Pamiętaj, że używasz Moq do kpienia z kontekstu ... I jeszcze nie zrobiłem nic z querystringiem (moje trasy nie zawierają żadnych zapytań).

var urlReferrer = Request.UrlReferrer; 
if (urlReferrer != null) 
{ 
    var url = "~" + Server.UrlDecode(urlReferrer.PathAndQuery); 

    // get routecollection 
    var routeCollection = new RouteCollection(); 
    GlobalApplication.RegisterRoutes(routeCollection); 

    // mcok context 
    var context = new Mock<HttpContextBase>(); 
    var request = new Mock<HttpRequestBase>(); 
    context.Expect(ctx => ctx.Request).Returns(request.Object); 

    // mock request 
    // TODO: convert querystring to namevaluecollection 
    // now it's just stripped 
    if (url.IndexOf('?') > 0) 
    { 
     url = url.Substring(0, url.IndexOf('?')); 
    } 

    var mock = Mock.Get(context.Object.Request); 

    // TODO: insert namevaluecollection of querystring 
    mock.Expect(req => req.QueryString).Returns(new NameValueCollection()); 
    mock.Expect(req => req.AppRelativeCurrentExecutionFilePath).Returns(url); 
    mock.Expect(req => req.PathInfo).Returns(string.Empty); 

    // get routedata with mocked context 
    var routeData = routeCollection.GetRouteData(context.Object); 
    var values = routeData.Values; 

    return RedirectToAction(routeData.Values["action"].ToString(), values); 
} 

Jak powiedziałem, to może trochę zbyt skomplikowana :)

+0

Tak samo jako dodatkowy komentarz, używam również powyższego kodu do modyfikowania niektórych wartości routedata. – Casper

0

Zawsze należy upewnić się, że adres URL jest odnosząc się w obrębie domeny i wiarygodne sznurka, które mogłyby być one pochodzą. W przeciwnym razie może to być wykorzystane w połączeniu z technologiami flash lub innymi technologiami po stronie klienta, takimi jak dzielenie odpowiedzi lub inne ataki, znane i nieznane.

Odnośnik HTTP to dane wprowadzane przez użytkownika i powinien zostać zatwierdzony, tak jak każdy inny.

Powiązane problemy