1

建築

ServiceContract と OperationContract による 2 つの操作を公開する単純な Web サービスの例があります。このサービスは、Adobe Flex 4 クライアントで使用する必要があります。残念ながら、Flex は SOAP 1.1 しか処理できない (SOAP 1.2 は処理できない) ため、WCF側でBasicHttpBindingを使用する必要があります。Web サービスへのアクセスを保護するために、基本認証を使用する必要があります。これは、両側 ( WCFFlex ) が理解できる唯一の認証方法であるためです。基本認証は SSL と共に使用され、トランスポートを暗号化します。Visual Studio 2012 を使用して IIS Express でサービスを実行しています。

WCF サービス構成

Web.config

<system.serviceModel>

<services>
  <service name="UserAuthentication.AuthenticationService"
           behaviorConfiguration="AuthenticationServiceBehavior">
    <endpoint address=""
              binding="basicHttpBinding"
              bindingConfiguration="AuthenticationBinding"
              contract="UserAuthentication.IAuthenticationService" />
    <endpoint contract="IMetadataExchange"
              binding="mexHttpBinding"
              address="mex" />
  </service>
</services>

<bindings>
  <basicHttpBinding>
    <binding name="AuthenticationBinding" maxReceivedMessageSize="65536">
        <!-- Use SSL (Transport) and MessageCredential by Username (referencing behaviors/serviceBehaviors/behavior/serviceCredentials) -->
        <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" proxyCredentialType="None" />
            <message clientCredentialType="UserName" />
        </security>
      <readerQuotas maxArrayLength="65536" maxBytesPerRead="65536" maxStringContentLength="65536"/>
    </binding>
  </basicHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="AuthenticationServiceBehavior">
      <serviceDebug includeExceptionDetailInFaults="false" />
      <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
      
      <!-- Use Custom DistributorValidator for Basic Authentication -->
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="UserAuthentication.DistributorValidator,UserAuthentication"/>
        <!--<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />-->
      </serviceCredentials>
      
      <!-- For Debug purpose: @see http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/ -->
      <serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

</system.serviceModel>

DistributedValidator.cs

基本認証からユーザー名とパスワードでユーザーを認証するために使用する必要があります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

namespace UserAuthentication
{
    public class DistributorValidator : UserNamePasswordValidator
    {
        /* Throw exeption to deny access for user */
        public override void Validate(string userName, string password)
        {
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                throw new SecurityTokenException("Username and password required");

            if( userName.Equals("user") == false || password.Equals("secretpwd") == false)
                throw new FaultException(string.Format("Wrong username ({0}) or password ", userName));
        }

    }
}

IIS Express で SSL を使用してサービスを開始する

  1. ソリューション エクスプローラーでプロジェクトを選択し、F4 キーを押してプロパティ パネルを開きます。
  2. SSL 有効化プロパティを True に設定します
  3. プロジェクトを実行するには、F11 キーを押します (ページの HTTP バージョンがブラウザーで開くはずです)。
  4. タスク バー トレイの IIS Express アイコンを右クリックし、ページの HTTPS バージョンを選択します。
  5. HTTPS 経由でサービスの WSDL ファイルを開くことができるようになりました

Flex で Web サービスを利用する

Adobe ドキュメントの説明に従って Web サービスに接続します。これは今のところ問題なく動作し、Flash Builder の[データ/サービス] パネルにサービスが作成されています。

問題

Flash Builder の[テスト操作] パネルを使用して Web サービスをテストします。結果は HTML ソース コードでhttps://localhost:44301/AuthenticationService.svcあり、期待される SOAP メッセージではありません。

無料版のSoapUIで同じ Web サービスと操作を試すと、次の SOAP エンベロープが得られます。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</faultcode>
         <faultstring xml:lang="de-AT">An error occurred when verifying security for the message.</faultstring>
      </s:Fault>
   </s:Body>
</s:Envelope>

さらに、MessageSecurityException がWindows イベント ビューアに記録されます

 Message authentication failed.
 Service: https://localhost:44301/AuthenticationService.svc
 Action: http://tempuri.org/IAuthenticationService/GetData
 ClientIdentity: 
 ActivityId: <null>
 MessageSecurityException: Security processor was unable to find a security header in the message. This might be because the message is an unsecured fault or because there is a binding mismatch between the communicating parties.   This can occur if the service is configured for security and the client is not using security.

どちらの場合も (Flex と SoapUI)、カスタム DistributorValidator はまったく変更されないため、問題は WCF の魔法の奥深くに置かれます。

質問

Adobe Flex とうまく連携する BasicHttpBinding と Basic Authentication を使用して WCF サービスを実行する可能性はありますか?

4

1 に答える 1