2008-10-08 3 views
7

Я использую атрибут аутентификации для некоторых моих действий на странице asp.net mvc, чтобы перенаправить людей на экран входа в систему, если они не прошли аутентификацию. Моя проблема возвращает их на ссылочную страницу после того, как они вошли в систему. Я просто отслеживал действие ссылки и ссылающийся контроллер, но это становится проблематичным, когда мне также нужно отслеживать некоторые параметры. Есть ли какой-нибудь изящный встроенный трюк, о котором я не знаю?Возврат к ссылке

ответ

3

В случае, если вы используете FormsAuthentication, когда ASP.NET перенаправляет пользователя на страницу входа в систему, то URL будет выглядеть примерно так:

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

атрибут действия формы входа должны иметь один и тот же параметр ReturnUrl (либо, как скрытый вход или как часть URL), так что FormsAuthentication может забрать его и перенаправить, например,

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

или

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

То, что я сделал для достижения этого результата, может переусердствовать, и я хотел бы увидеть и другие методы. Однако, вот мой код.

Обратите внимание, что это использование Moq для издевательства контекста ... И я еще ничего не сделал с querystring (мои маршруты не содержат никаких запросов).

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

Как я уже сказал, это может быть немного усложненной :)

+0

Как дополнительный комментарий, я также использую приведенный выше код, чтобы изменить некоторые значения routingata. – Casper 2008-10-08 08:21:09

0

Вы всегда должны убедиться, что ссылающийся URL находится в пределах домена и правдоподобной строки, что они могут быть откуда. В противном случае это может использоваться со вспышкой или другими технологиями на стороне клиента, чтобы делать такие вещи, как ответное расщепление или другие атаки, известные и неизвестные.

HTTP-референт является пользователем, и он должен быть проверен, как и любой другой.

Смежные вопросы