Исключить конкретный путь из авторизации WIF в проекте ASP.NET MVC 4
Мы успешно создали фон идентификации Windows (WIF) в нашем проекте ASP.NET 4.5 MVC 4 с помощью расширения Идентификация и доступ... для Visual Studio 2012. Но не могут исключить определенный путь от авторизации, чтобы разрешить анонимный доступ.
Когда мы получаем доступ к нашему маршруту по умолчанию (т.е. /Home
), пассивное перенаправление перенаправляет нас на настроенный эмитент Uri. Это верно. Но теперь предположим, что мы хотим исключить Path /Guest
из STS Authentication, чтобы каждый мог получить доступ к http://ourhost/Guest
, не направляясь к эмитенту STS. Там находятся только статические документы.
Фрагменты из Web.config
:
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value="http://ourhost/" />
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<trustedIssuers>
<add thumbprint="9B74****40D0" name="OurSTS" />
</trustedIssuers>
</issuerNameRegistry>
<certificateValidation certificateValidationMode="None" />
</identityConfiguration>
</system.identityModel>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="false" />
<wsFederation passiveRedirectEnabled="true" issuer="http://oursts/Issue" realm="http://ourhost/" reply="http://ourhost/" requireHttps="false" />
</federationConfiguration>
</system.identityModel.services>
Далее мы имеем...
<system.webServer>
<!-- ... -->
<modules runAllManagedModulesForAllRequests="true">
<add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
и, наконец:
<system.web>
<!-- ... -->
<authentication mode="None" />
</system.web>
Мы пробовали следующее без успеха:
<location path="~/Guest"> <!-- also "/Guest" is not working -->
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Мы также попытались поместить небольшой файл Web.config в эту папку без успеха. Независимо от того, какой Uri мы находим в браузере, мы всегда перенаправляемся.
Каков правильный способ выполнить это?
ИЗМЕНИТЬ
Убрали предыдущий "принятый ответ", установите "принятый ответ" на Eugenios answer, так как это более полезный ответ.
Ответы
Ответ 1
В приложении MVC вы обычно определяете доступ через атрибут [Authorize]
в контроллерах и действиях.
Просто удалите из web.config:
<system.web>
<authorization>
<deny users="?" />
</authorization>
Примечание. Обычно это добавляется автоматически с помощью мастера "Добавить STS Reference" в VS2010
Похоже, что поведение на VS2012 и новых инструментах одинаково. Я просто создал совершенно новое приложение MVC4. Удалил инструмент "Идентификация и доступ..." с локальной конфигурацией STS (оставил все значения по умолчанию).
Он добавил этот фрагмент в web.config:
<authorization>
<deny users="?" />
</authorization>
Я удалил его и добавил [Authorize]
в действие "О программе":
[Authorize]
public ActionResult About()
{
ViewBag.Message = "Your app description page.";
return View();
}
Когда я нажимаю ссылку "О", я перенаправляюсь к STS. Все остальное работает с анонимным доступом.
Примечание:
У вас есть контроль над этим тоже в мастере (см. страницу "Конфигурация" мастера).
Ответ 2
Я не могу заставить [Authorize]
работать - он не выполняет перенаправление на мой STS, и я уверен, что это то, чего я не вижу. Однако я выяснил, как решить исходный вопрос.
В global.asax
:
protected void Application_Start()
{
... config stuff ...
FederatedAuthentication.WSFederationAuthenticationModule.AuthorizationFailed += WSFederationAuthenticationModule_AuthorizationFailed;
}
а затем:
void WSFederationAuthenticationModule_AuthorizationFailed(object sender, AuthorizationFailedEventArgs e)
{
// Do path/file detection here
if (Request.Path.Contains("/Content/") || Request.Path.Contains("/Scripts/"))
{
e.RedirectToIdentityProvider = false;
}
}
Ответ 3
Что в конечном итоге указывало мне на правильное направление, было более старое сообщение , в котором объясняется, как защитить определенный контроллер или области страницы. В сочетании с глобальными фильтрами я почти там.
Кажется, что ключ не должен использовать параметр passiveRedirectEnabled="true"
, но установить его на false
. Только тогда у вас есть полный контроль над процессом аутентификации, но вам нужно будет инициировать пассивное перенаправление самостоятельно, используя класс SignInRequestMessage
(который это не большое дело).
Приветствуются лучшие решения с меньшим количеством кода.
ИЗМЕНИТЬ
Для этого убрано "принятое состояние ответа", установите "принятый ответ" на Eugenios anwer, так как это более полезный ответ.
Ответ 4
Я был в той же ситуации, что и Томас. В моем случае я тестировал/использовал локальный IISExpress.
Ответ Eugenio почти заставил меня работать, с одним дополнительным требованием. Мне пришлось установить "Анонимная аутентификация" в моем MVC Project Property на "Enabled".
Это было отключено по умолчанию или, возможно, установлено таким образом при использовании инструментария "Идентификация и доступ..." VS 2012.
Итак, чтобы повторить, не было никакого кода или специальных атрибутов для записи/поддержки.
Мой файл csproj содержит:
<IISExpressAnonymousAuthentication>enabled</IISExpressAnonymousAuthentication>
Мой файл web.config содержит:
<system.web>
<authentication mode="None" />
</system.web>
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
</modules>
</system.webServer>
<system.identityModel.services>
<federationConfiguration>
<wsFederation passiveRedirectEnabled="true" issuer="https://REMOVED.accesscontrol.windows.net/v2/wsfederation" realm="urn:REMOVED" requireHttps="false" />
</federationConfiguration>
</system.identityModel.services>
И я добавляю стандартный атрибут [Authorize] к действиям контроллера, которые я хочу защитить WIF:
[Authorize]
public ActionResult About()
{
....
}