建築
ServiceContract と OperationContract による 2 つの操作を公開する単純な Web サービスの例があります。このサービスは、Adobe Flex 4 クライアントで使用する必要があります。残念ながら、Flex は SOAP 1.1 しか処理できない (SOAP 1.2 は処理できない) ため、WCF側でBasicHttpBindingを使用する必要があります。Web サービスへのアクセスを保護するために、基本認証を使用する必要があります。これは、両側 ( WCFとFlex ) が理解できる唯一の認証方法であるためです。基本認証は 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 を使用してサービスを開始する
- ソリューション エクスプローラーでプロジェクトを選択し、F4 キーを押してプロパティ パネルを開きます。
- SSL 有効化プロパティを True に設定します
- プロジェクトを実行するには、F11 キーを押します (ページの HTTP バージョンがブラウザーで開くはずです)。
- タスク バー トレイの IIS Express アイコンを右クリックし、ページの HTTPS バージョンを選択します。
- 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 サービスを実行する可能性はありますか?