Звонки в сервис Wcf запрещены?Это проблема с веб-конфигурацией? - PullRequest
2 голосов
/ 24 января 2011

У меня есть служба WCF ... которая будет находиться на Azure.Я добавил аутентификацию и авторизацию форм с помощью следующей конфигурации в файле web.config:

<system.web>
        <compilation debug="true" targetFramework="4.0" />
        <authentication mode="Forms">
            <forms loginUrl="blah.svc" timeout="2880" />
        </authentication>
        <membership defaultProvider="SqlMembershipProvider">
            <providers>
                <add connectionStringName="blah" applicationName="blah_app" name="SqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" />
            </providers>
        </membership>
        <profile>
            <providers>
                <add name="SqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="blah" applicationName="blah_app" />
            </providers>
        </profile>
        <roleManager enabled="true" defaultProvider="SqlRoleProvider">
            <providers>
                <add connectionStringName="blah" applicationName="blah_app" name="SqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
            </providers>
        </roleManager>
    </system.web>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="wsHttp">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                    <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="SqlRoleProvider" />
                    <serviceCredentials>
                        <serviceCertificate x509FindType="FindBySubjectName" storeName="My" storeLocation="LocalMachine" findValue="blah_cert" />
                    </serviceCredentials>

                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
        <services>
            <service name="blah_app.blah" behaviorConfiguration="wsHttp">
                <endpoint address="" contract="blah_app.iblah" binding="wsHttpBinding" />
            </service>
        </services>
    </system.serviceModel>

Проблема, с которой я сталкиваюсь, заключается в том, что любые вызовы веб-службы от клиента поступают как отказано!*

public class Blah:IBlah
{
[PrincipalPermission(SecurityAction.Demand, Role = "BlahOppRole")]
        public BlahResponse Blah(BlahRequest BlahRequest)
        {
            BlahResponse = new BlahResponse();


            return response;
        }
}

Мой клиент - консольное приложение для Windows.Он имеет следующую конфигурацию:

<system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IBlah" 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="Message">
                        <transport clientCredentialType="Digest" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" negotiateServiceCredential="true"
                            algorithmSuite="Default" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://127.0.0.1:89/Blah.svc"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IBlah"
                contract="Data.Blah" name="WSHttpBinding_IBlah">
                <identity>
                    <dns value="blah_cert"/>
                </identity>
            </endpoint>
        </client>

Ответы [ 2 ]

1 голос
/ 25 января 2011

Ну, Так как я использовал самозаверяющий сертификат ... клиент расстроился из-за подлинности этого сертификата. Распространенными ошибками были AccessDenied (из-за неправильной настройки службы), а также «Произошла ошибка при согласовании учетных данных службы ...» или что-то в этом роде. Короче говоря, после прочтения поста этого замечательного сотрудника (Спасибо, Dev @ Work) Dev @ Work Мне удалось изменить его работу и добавить аутентификацию и авторизацию форм ASP.NET через провайдеров членства и роли на услуга.

Подводя итог, можно сказать, что у Dev @ Work была очень веская точка зрения. Клиенты WCF будут кричать о самозаверяющих сертификатах. Хитрость в том, чтобы сделать службу wcf полезной на сервере dev, заключается в том, чтобы лгать клиентам службы о подлинности сертификата, используемого для кодирования учетных данных клиента. Для этого любой wcf-клиент должен иметь поведениеConfiguration со своим serviceEndpoint и использовать собственный механизм проверки сертификата для аутентификации сертификата сервера. Это делается путем создания объекта, который наследуется от System.IdentityModel.Selectors.X509CertificateValidator , и путем переопределения метода Validate() указанного объекта. Проверка успешна, если указанный объект не выдает ошибки:

<client>
            <endpoint address="http://machine:5101/blah.svc"
                binding="wsHttpBinding" bindingConfiguration="WsHttpBinding_Iblah"
                contract="Data.Iblah" name="WsHttpBinding_Iblah" behaviorConfiguration="BehaviorConfig">
                <identity>
                    <certificate encodedValue="..." />
                </identity>
            </endpoint>
        </client>

        <behaviors>
            <endpointBehaviors>
                <behavior name="BehaviorConfig">
                    <clientCredentials>
                        <serviceCertificate>
                            <authentication certificateValidationMode="Custom" customCertificateValidatorType="BlahConsole.X509Validator, BlahConsole"/>
                        </serviceCertificate>
                    </clientCredentials>        
                </behavior>
            </endpointBehaviors>
        </behaviors>

И пользовательский валидатор:

internal class X509Validator : System.IdentityModel.Selectors.X509CertificateValidator
    {
        public override void Validate(X509Certificate2 certificate)
        {
            // validate argument
            if (certificate == null)
                throw new ArgumentNullException("Certificate is null");
        }
    }
1 голос
/ 24 января 2011

В этой статье MSDN содержится хорошая пошаговая инструкция по настройке WsHttpBinding с аутентификацией UserName.

В основном вам придется

  • Установите режим безопасности на TransportWithMessageCredential (Шаг 6)
  • Добавить поведение службы ServiceCredentials и настроить userNameAuthentication (Шаг 8)
  • Измените свое клиентское приложение, чтобы задать имя пользователя и пароль (шаг 12)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...