У меня есть веб-приложение, использующее IIS 10 с включенной аутентификацией Windows и анонимной аутентификацией. Приложение использует SignalR 2.4.0 и зависимость от SQL для циклического просмотра изображений каждые десять секунд, пользователь может использовать устройство, чтобы остановить цикл и отобразить презентацию в своем собственном темпе, прежде чем вернуться в цикл.
Проблема, с которой я сталкиваюсь, заключается в том, что большинство приложений должны использовать проверку подлинности Windows, а некоторые контроллеры должны разрешать анонимный доступ. Однако анонимный пользователь (например, Smart TV или компьютер, не подключенный к домену) не может отображать изображения без предварительной аутентификации.
Я мог бы неправильно понять ситуацию, но я полагаю, что это потому, что signalR использует аутентификацию Windows. Если я закрою диалоговое окно с запросом имени пользователя и пароля, консоль для Microsoft Edge отобразит следующее сообщение
HTTP401: DENIED - Запрошенный ресурс требует аутентификации пользователя.
(XHR) GET - http://MyWebsite/Home/signalr/negotiate?clientProtocol=2.0&connectionData=%5B%7B%22name%22%3A%22signalrhub%22%7D%5D&_=1557410422010
Большинство изменений кода, которые я пробовал, были в файле web.config. Основной файл web.config имеет режим аутентификации
<authentication mode="Windows" />
Однако у меня также есть выпуск web.config, который содержит настройку, разрешающую анонимность для контроллера дисплея и сигнализатора
<location path="Area/Controller" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
<location path="signalr" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
Сначала я подумал, что мне нужно добавить подстановочный знак для пути местоположения, чтобы он выглядел примерно так:
<location path="signalr/*" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
или
<location path="signalr/negotiate*" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
но при поиске и тестировании он, кажется, не принимает его.
Я также пытался явно разрешить анонимную аутентификацию для путей, но я получил ошибку 500, прежде чем она достигла стадии аутентификации
<location path="Area/Controller" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
<location path="signalr" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
Я также установил контроллер, чтобы разрешить анонимный
[AllowAnonymous]
public class Controller
{
}
PartialView, выполняющий сценарий signalR, запрашивает аутентификацию при достижении connection.hub.start
<input type="hidden" name="connectionId" id="connectionId" />
<div id="divImageViewer"></div>
@Scripts.Render("~/bundles/jquery_signalR")
<script src="@Model.SignalRHubsUrl" type="text/javascript"></script>
@Html.HiddenFor(model => Model.MyModel.ModelItem)
<script type="text/javascript">
$(function () {
setTimeout(function () {
$.connection.hub.start()
.done(function () {
console.log("starting..."); //doesn't display in the console
var cid = $.connection.hub.id;
$("#connectionId").val(cid);
console.log("connected! Id: " + cid);
//do stuff
})
.fail(function (reason) {
console.log("SignalR connection failed: " + reason); //does display in the console after closing the dialog box
});
}, 5000); // Start connection after 5 seconds.
}
</script>
В конечном счете, я бы хотел сохранить аутентификацию Windows на месте для большинства веб-приложений, но при этом разрешить анонимный доступ для некоторых небольших частей.
Также извините, если большая часть этого - бесполезная тарабарщина, многое из этого все еще ново для меня, особенно javascript и jquery.