У меня проблема с получением веб-приложения MVC с HTTPS для вызова службы WCF, которая также использует HTTPS.Веб-приложение MVC должно пройти проверку подлинности с помощью сертификата службы WCF.
Я использую Windows 7, IIS 7.5, VS 2010 с C # и .NET Framework 4.0.
Вот что яуже сделано:
Я создал центр сертификации под названием «Центр разработки»:
makecert -pe -n "CN=Development Authority" -ss my -sr LocalMachine -a sha1 -sky signature -r "c:\Development Authority.cer"
Я импортировал новый сертификат с помощью инструмента MMC вПапка «Доверенные корневые центры сертификации» и в папке «Сторонние корневые центры сертификации» (локальный компьютер).Этот сертификат также можно найти в папке «Personal».
Я видел, что если я импортирую CA только в «Trusted Root CA», он все равно выдаст предупреждение «not trust».После импорта ЦС в папку «Сторонний корневой ЦС» предупреждение исчезло.
Я создал два других сертификата (подписанных вновь созданным ЦС), используя следующую команду:
makecert -pe -n "CN=mvc.localhost" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in "Development Authority" -is MY -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 c:\mvc.localhost.cer
Таким образом, я создал сертификаты 'mvc.localhost' и 'wcf.localhost'.Я импортировал их в папку «Личные» (для локального компьютера) с помощью инструмента MMC.
В файлах хостов Windows я создал два псевдонима для двух приложений, которые будутразмещены с IIS (приложение MVC и приложение службы WCF).Я обновил свой файл hosts следующими строками:
#development
127.0.0.1 mvc.localhost
127.0.0.1 wcf.localhost
В IIS я сопоставил новый веб-сайт mvc.localhost с очень простым веб-приложением MVC.Я также сопоставил новый веб-сайт 'wcf.localhost' с базовой вновь созданной службой WCF.
mcv.localhost:
Пул приложений: .NET Framework 4.0, запущенная с использованием ApplicationPoolIdentity.
Анонимная аутентификация : включена и установлена на «Определенный пользователь»: «IUSR».
Привязки:
HTTP (имя хоста 'mvc.localhost', порт 80) -> может получить доступ с помощью http://mvc.localhost/'
HTTPS (имя хоста 'mvc.localhost ', порт 1234) -> может получить доступ с помощью' https://mvc.localhost:1234/'., добавленного с сертификатом 'mvc.localhost'.
wcf.localhost:
Пул приложений: .NET Framework 4.0, работающий с использованием ApplicationPoolIdentity.
Анонимная аутентификация : включен и установлен на «Определенный пользователь»':' IUSR '.
Привязки:
HTTP (имя хоста' wcf.localhost ', порт 80) -> можно получить с помощью'http://wcf.localhost/'
HTTPS (имя хоста 'wcf.localhost ', порт 443) -> может получить доступ с помощью https://wcf.localhost/'., добавленного с сертификатом' wcf.localhost '.
Чтобы изменить имена хостов для привязок HTTPS, я использовал следующую команду:
c:\Windows\System32\inetsrv>appcmd set site /site.name:"wcf.localhost" /bindings.[protocol='https',bindingInformation='*:443:'].bindingInformation:*:443:wcf.localhost
Я проверил два веб-сайта отдельно с HTTPS, и они работали без проблем (за исключением Firefox, который имеет строгую политику, когда я обращаюсь к локальным сертификатам, созданным для целей тестирования, и дает вампредупреждение 'sec_error_unknown_issuer', но пока это не моя проблема).
Конфигурация службы WCF для проверки подлинности сертификата:
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="wcf.localhost.WelcomeService" behaviorConfiguration="wcf.localhost.WelcomeServiceBehavior">
<endpoint address="https://wcf.localhost/WelcomeService.svc" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="wcf.localhost.IWelcomeService">
</endpoint>
<!--<endpoint address="mex" binding="mexHttpsBinding"
name="mexEndpoint" contract="IMetadataExchange"/>-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="wcf.localhost.WelcomeServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<clientCertificate>
<authentication revocationMode="NoCheck" certificateValidationMode="PeerOrChainTrust" />
</clientCertificate>
<serviceCertificate findValue="<<wcf.localhost Certificate Thumbprint inserted here>>" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
В IIS для настроек SSL я устанавливаю «Требовать SSL» с опцией «Требовать».
Служба WelcomeService предоставляет метод под названием «SayHello (string)», который объединяет «Hello» свходной параметр и возвращает новую строку.
Я могу достичь 'https://wcf.localhost/welcomeservice.svc' без проблем.
Веб-приложение MVC конфигурация:
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IWelcomeService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://wcf.localhost/WelcomeService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IWelcomeService"
contract="WelcomeService.IWelcomeService" name="WSHttpBinding_IWelcomeService" behaviorConfiguration="CustomBehavior">
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior" >
<clientCredentials>
<clientCertificate findValue="<<mvc.localhost Certificate Thumbprint inserted here>>"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindByThumbprint"/>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"></authentication>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Теперь к проблеме: После использования приложения MVC для вызова службы WCF я получаю следующую ошибку:
Описание: необработанное исключениепроизошло во время выполнения текущего веб-запроса.Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.
Exception Details: System.Net.WebException: The remote server returned an error: (403) Forbidden.
Source Error:
Line 48:
Line 49: public void SayHello(string name) {
Line 50: base.Channel.SayHello(name);
Line 51: }
Line 52: }
Source File: C:\Projects\ssl.research\mvc.localhost\Service References\WelcomeService\Reference.cs Line: 50
Stack Trace:
[WebException: The remote server returned an error: (403) Forbidden.]
System.Net.HttpWebRequest.GetResponse() +7859156
System.ServiceModel.Channels.HttpChannelRequest.WaitForReply(TimeSpan timeout) +99
[MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +4727747
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +1725
mvc.localhost.WelcomeService.IWelcomeService.SayHello(String name) +0
mvc.localhost.WelcomeService.WelcomeServiceClient.SayHello(String name) in C:\Projects\ssl.research\mvc.localhost\Service References\WelcomeService\Reference.cs:50
mvc.localhost.Controllers.HomeController.CallService(HomeModel model) in C:\Projects\ssl.research\mvc.localhost\Controllers\HomeController.cs:33
lambda_method(Closure , ControllerBase , Object[] ) +127
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +264
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +129
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +826410
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +314
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +825632
System.Web.Mvc.Controller.ExecuteCore() +159
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +54
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.237
На стороне клиента я тоже пробовал:
ServicePointManager.ServerCertificateValidationCallback += customXertificateValidation
...
private static bool customXertificateValidation(object sender, X509Certificate cert,
X509Chain chain, SslPolicyErrors error)
{
return true;
}
- Использование отпечатка сертификата службы для аутентификации в службе.
- Различные значения CertificateValidationMode.
Ничего не работает.
Я использовал SSL Diagnostics 1.1 для проверки двух веб-приложений и их сертификатов.Ошибок не было показано.Симуляция SSL Handshake прошла нормально, без ошибок.
Я чувствую, что довольно близка к завершению тестового проекта (решив другие проблемы на этом пути).
При поиске в Интернете я мог найти только службы HTTP WCF или службы WCF, которые не используют сертификат для проверки подлинности, или службы WCF, которые используют проверку подлинности сертификата, но являются HTTP.
Я пытаюсь, чтобы веб-приложение MVC, работающее по протоколу HTTPS, вызывало службу HTTPS, работающую под управлением WCF, для которой требуется сертификат для аутентификации.
Многие замечательные статьи помогли мне решить другие проблемы сэтот проект.
Теперь я застрял и не могу найти решение.
Любое предложение приветствуется.
Спасибо, Богдан.
ОБНОВЛЕНИЕ
Я заметил, что оба моих сертификата имеют свои цели: «Обеспечивает идентификацию удаленного компьютера» (serverAuth) но я не вижу ничего о clientAuth.
Кроме того, браузер Chrome предлагает мне выбрать сертификат при доступе к веб-приложению MVC.В списке сертификатов я не вижу двух сертификатов, которые я создал.
Я вижу только один сертификат, который имеет одну из своих целей (но отличается от сертификата, который я планирую использовать!): «Подтверждает вашу личность на удаленном компьютере»
Может быть, поэтому я получаю ошибку?Может быть, я не могу использовать ни один из своих недавно созданных сертификатов для аутентификации клиента на сервере?
Есть мысли?Если я прав, как я могу добавить цель clientAuth к любому из моих сертификатов?Спасибо