Идентификатор входа в систему ASP.Net для переадресации протокола (Https)
Надеюсь, я просто пропустил что-то действительно простое/очевидное - почему, и что более важно, как вы поддерживаете (или усиливаете) протокол во время перенаправления на Login
?
Чтобы проиллюстрировать:
![request trace]()
- исходный протокол
https
-
можно подумать, что это должно быть "по умолчанию" для чего-то вроде Login
, но, как показано, перенаправление (кажется) не поддерживает его.
Материал, который я пробовал:
-
Существует атрибут RequireHttps
, который можно использовать, но:
- кажется "странным", что для получения "там" потребуется 2 переадресации
- в ситуациях, когда у вас есть балансировщик нагрузки и/или выгружаете SSL в другом месте (а не на сервере), тогда это будет цикл переадресации (SSL между клиентом и интерфейсом net/ssl lb и
http
к вашему ящику/приложению). Это на самом деле мой производственный случай...
-
Я уже переписал URL-адрес URL-адреса IIS (aka canonical) для https для всего сайта), , и это кажется "проигнорированным" (тоже) (правило не проверяет "https", иначе оно будет иметь такой же цикл переадресации).
-
попробовал и не смог установить абсолютный URL-адрес в LoginPath
(в CookieAuthenticationOptions
).. потому что вы не можете этого сделать...
Спасибо за советы или указатели...
Update
Что касается "почему" ?
- в ситуациях, когда у вас есть балансировщик нагрузки и/или выгружаете SSL в другом месте (а не на сервере), тогда это будет цикл переадресации (SSL находится между клиентом и интерфейсом net/ssl lb и
http
к вашему ящику/приложению). Это на самом деле мое производство случай..
Дальнейшее вмешательство привело меня к вышесказанному, как показано в этой последовательности (localhost - мой локальный dev, а не сервер) (указанная выше проблема проявляется в балансированной рабочей нагрузке среде, где обработка SSL "вверх по стеку" - например ARR):
![localhost https]()
- протокол фактически поддерживается
- проблема кажется ровно, связанной с ситуацией, когда приложение и "инфраструктура" не соответствуют друг другу. Похоже на ситуацию, когда в коде вы делаете
Request.IsSecureConnection
в среде с балансировкой нагрузки/веб-фермы (например, скажем ARR, где cert
находится в вашем ARR, а не в вашем хосте /s ). Эта проверка всегда будет возвращать false
в такой ситуации.
Итак, вопрос действительно в руководстве , как, чтобы обойти это?
Обновление 2
Большое спасибо Ричарду за то, что он изменил мое "направление", пытаясь решить это. Я изначально искал способ:
-
установить/сообщить OWIN/Identity использовать безопасный URL (явно) и "переопределить" способ оценки LoginPath
. Опция Secure
(only) при обработке файлов cookie каким-то образом привела меня таким образом (если я могу явно указывать файлы cookie только в HTTPS, то это вроде как дало мне представление о возможности сделать это для LoginPath
.. в один конец или другой)
-
"Хакерный" способ в моей голове состоял в том, чтобы просто обработать его на стороне клиента (Javascript).
В конце концов, Ричард ответ взял меня на URL Rewriting (хотя все еще не на стороне LB, потому что это не под моим контролем). В настоящее время я работаю (на основе моей среды):
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_CLUSTER_HTTPS}" pattern="^on$" negate="true" />
<add input="{HTTP_CLUSTER_HTTPS}" pattern=".+" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{SCRIPT_NAME}/{REQUEST_URI}" redirectType="SeeOther" />
</rule>
и увидеть некоторый свет в конце туннеля.
Обновление 3
Удивительная благодарность Ричарду за слежку! Последний ответ заставил меня тоже замолчать, и там оказалось довольно несколько сообщений здесь, на SO, связанных с CookieApplyRedirectContext... так что теперь это то, что у меня на месте (что характерно для моего случая), и это то, что я изначально собирался после:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
//This is why. If I could explicitly set this, then I (thought) I should
//be able to explicitly enforce https (too..as a setting)
//for the LoginPath...
CookieSecure = CookieSecureOption.Always,
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = .....
,
OnApplyRedirect = context =>
{
Uri absoluteUri;
if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out absoluteUri))
{
var path = PathString.FromUriComponent(absoluteUri);
if (path == context.OwinContext.Request.PathBase + context.Options.LoginPath)
{
context.RedirectUri = context.RedirectUri.Replace("http:", "https:");
}
}
context.Response.Redirect(context.RedirectUri);
}
}
});
Ответы
Ответ 1
Эта проблема возникает, потому что ваше приложение отправляет перенаправление на абсолютный URL-адрес. Вы можете исправить это одним из двух способов: в балансировщике нагрузки или в самом приложении.
Балансировщик нагрузки
Настройте балансировщик нагрузки, чтобы переписать ответы перенаправления с http на https. Если вы использовали ARR, следующее правило (взятое из здесь) должно работать:
<rule name="forum-redirect" preCondition="IsRedirection" enabled="true">
<match serverVariable="RESPONSE_LOCATION" pattern="^http://[^/]+/(.*)" />
<conditions>
<add input="{ORIGINAL_HOST}" pattern=".+" />
</conditions>
<action type="Rewrite" value="http://{ORIGINAL_HOST}/{R:1}" />
</rule>
Другие балансировки нагрузки потребуют аналогичной конфигурации.
Применение
Мы можем заменить URL-адрес, который OWIN перенаправляет в процессе авторизации с относительным URL-адресом, что означает, что протокол останется таким, каким ранее пользовался браузер.
В источнике Owin потребовалось немного копания, чтобы найти, как это сделать, но следующее изменение для запуска приложения должно решить ваши проблемы. Сначала извлеките инициализацию CookieAuthenticationProvider из конфигурации запуска.
Изменить:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Move these options in the step below...
}
});
To:
var cookieProvider = new CookieAuthenticationProvider
{
// ... Options from your existing application
};
// Modify redirect behaviour to convert login URL to relative
var applyRedirect = cookieProvider.OnApplyRedirect;
cookieProvider.OnApplyRedirect = context =>
{
if (context.RedirectUri.StartsWith("http://" + context.Request.Host))
{
context.RedirectUri = context.RedirectUri.Substring(
context.RedirectUri.IndexOf('/', "http://".Length));
}
applyRedirect(context);
};
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = cookieProvider
});
Пока мы не можем получить доступ к правилу перенаправления, OWIN использует делегат для выполнения фактического перенаправления. То, что я здесь сделал, это сохранить делегат, изменить URL-адрес, который он должен будет предоставить, а затем снова вызвать его.
С помощью этой опции убедитесь, что любые другие перенаправления и ссылки на вашем сайте относительны.
Ответ 2
Это небольшая модификация опции "Приложение" в Ответ Ричарда. Некоторые из манипуляций с строками делегируются в класс Uri.
var cookieProvider = new CookieAuthenticationProvider
{
// ... Options from your existing application
};
// Modify redirect behaviour to convert login URL to relative
var applyRedirect = cookieProvider.OnApplyRedirect;
cookieProvider.OnApplyRedirect = context =>
{
var redirectUri = new Uri(context.RedirectUri, UriKind.Absolute);
if (redirectUri.Scheme == "http" && redirectUri.Host == context.Request.Uri.Host)
{
context.RedirectUri = redirectUri.PathAndQuery;
}
applyRedirect(context);
};
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = cookieProvider
});