Проверка подлинности по формам + абсолютный возврат ASP.NET MVC - PullRequest
11 голосов
/ 19 декабря 2008

У меня есть приложение центральной аутентификации на сервере а. На сервере b есть одно или несколько приложений в одном домене, которые должны проходить аутентификацию на сервере a. Это достаточно легко настроить, чтобы приложения сервера b перенаправлялись на сервер a. Что не так просто, так это вернуть ReturnURL в абсолют.

Вот морщина. Приложение потребления на сервере b имеет два контроллера, один общедоступный и один защищенный. Если украшение [authorize] помещено в публичное действие (которое является контроллером по умолчанию), я получаю правильный абсолютный URL. Однако, если это в его собственном контроллере, я получаю относительный URL.

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

Идеи

Ответы [ 3 ]

15 голосов
/ 19 декабря 2008

Стандарт работает как AuthorizeAttribute, устанавливая код состояния ответа на 401, если запрос не аутентифицирован. Это запускает стандартный ответ модуля аутентификации по умолчанию на неавторизованный запрос. Я предполагаю, что вы используете аутентификацию на основе форм, которая создаст URL-адрес возврата на основе URL-адреса в запросе. В этом случае, вероятно, относительный URL.

Одна вещь, которую вы могли бы сделать, вместо того, чтобы полагаться на встроенное поведение, вы могли бы реализовать SSOAuthorizeAttribute, который расширяет класс AuthorizeAttribute и переопределяет OnAuthorization. Затем вы можете извлечь loginUrl из элемента формы в веб-конфигурации и создать собственный RedirectResult и извлечь returnUrl из свойства HttpContext.Request.Url.AbsoluteUri в параметре AuthorizationContext.

 public class SSOAuthorizeAttribute : AuthorizeAttribute
 {
      public override void OnAuthorization( 
                          AuthorizationContext filterContext )
      {
          if (filterContext == null)
          {
              throw new ArgumentNullException( "filterContext" );
          }

          if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
          {
              // get from cached variable from web configuration
              string loginUrl = ... 
              if (filterContext.HttpContext.Request != null)
              {
                  loginUrl += "?ReturnUrl=" + filterContext.HttpContext
                                                           .Request
                                                           .Url
                                                           .AbsoluteUri;
              }

              filterContext.Result = new RedirectResult( loginUrl );
          }
      }
 }
5 голосов
/ 25 февраля 2009

Предполагая аутентификацию форм, в приложениях сервера B web.config установите атрибут loginUrl в теге форм для метода действия контроллера, который привязывается к абсолютному URL-адресу перед перенаправлением на сервер A.

Конфиг на сервере B

<authentication mode="Forms">
  <forms loginUrl="/Account/LoginRedirect" />
</authentication>

Метод действия будет выглядеть как

 public RedirectResult LoginRedirect(string returnUrl)
    {
       var requestUrl = HttpContext.Current.Request.Url;
       return LoginUrlOnServerA + 
              "?returnUrl=" +          
              HttpUtility.UrlEncode(string.Format("http://{0}:{1}{2}",
                requestUrl.Host,
                requestUrl.Port,
                HttpUtility.UrlDecode(returnUrl)));
     }
0 голосов
/ 04 июня 2012

как https://stackoverflow.com/a/583608/80589 но короче:

public RedirectResult LogOn(string returnUrl)
{
  var r = new Uri(Request.Url, returnUrl).ToString();
  return Redirect("https://logonserver.com/?return_url=" + Url.Encode(r));
}
...