3

私はWCFを初めて使用し、クライアントごとにいくつかのカスタマイズ設定を維持し、サービスにアクセスするユーザーをログに記録するためにユーザー/パスワードスキーマが必要なサーバー/クライアントアプリケーションを作成していますが、トラフィックの「セキュリティ」情報は機密情報ではないため、ネット経由は実際には必要ありません。これを考慮して、これを達成する簡単な方法を探していましたが、見つかりませんでした。

いくつかの制約と条件があります。

  • Windows セキュリティはオプションではありません。
  • 私は clickonce デプロイメントを使用しているため、すべてがインストール パケットに含まれている必要があります。ダウンロードしているユーザーの実際のリストがわからないため、一部の証明書をすべてのユーザーに配布する方法がありません。
  • また、クライアントは LAN 内および複数の WAN 経由でアクセスされます。別の要件を満たす必要があるのは、応答ごとに大量のデータが流れるため、サービスのパフォーマンスが非常に優れている必要があるため、質問は次のとおりです。

メッセージ セキュリティがパフォーマンスを低下させることはよく知られていますか?

「手動」の方法は、公開している各メソッドのパラメーターとしてユーザー名を渡すことですが、非常に汚い解決策のようです。

これを設計するには多くの制約があるように思われるので、これについて質問しています。

これを達成するための最も簡単な解決策はどれですか?

4

1 に答える 1

3

まず、サービスを利用するすべてのユーザーが何らかの方法でサービスを利用するために「登録」されていると想定する必要があります。公開されていて匿名の場合、追跡はまったく行われないからです。したがって、私の仮定は次のとおりです。

  1. このサービスは、TCP エンドポイントをサポートするために Windows Service/WinForms でホストされます。- IIS の新しいバージョン (>6) では、これは必須の仮定ではなくなりました。
  2. 認証には「UserName/Password」のような組み合わせがあります。これは Active Directory にはありません (Windows 認証を選択していません) が、xml/database である可能性があります。
  3. 私たちは次のような方法を望んでいませんpublic int Add(string User, string Password, int A, int B)

このようなことを行う TCP エンドポイントを持つサービスがあります。それを共有します。それがベストプラクティスであるとは主張しません。

アプリケーション名はMYAPPです

私は提供しました

customUserNamePasswordValidatorType="MYAPPHost.Authenticate, MYAPPHost" 

serviceCredentials > userNameAuthentication 

web.config のセクション。

MYAPPHost は、私の Windows サービスの名前です。Authenticateデータベースからの認証を行うクラスです。

message clientCredentialType="UserName"TCPBinding に設定されます。

私のWindowsサービスのApp.Config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
          switchValue="Off" propagateActivity="true" >
        <listeners>
          <add name="SERVICE_MONITOR" type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="MYAPP_MONITOR.svclog" />
        </listeners>
      </source>      
      <source name="MYAPP_TRACE" switchValue="All" >
        <listeners>
          <add name="MYAPP_TRACE_LISTENER" type="System.Diagnostics.XmlWriterTraceListener"                                         
               initializeData="MYAPP_TRACE.svclog" />
        </listeners>
      </source>
    </sources>
    <trace autoflush="true" />
  </system.diagnostics> 

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="OverAllServiceBehavior">
          <serviceSecurityAudit 
            auditLogLocation="Application" 
            serviceAuthorizationAuditLevel="Failure" 
            messageAuthenticationAuditLevel="Failure" 
            suppressAuditFailure="true" />          
          <serviceDebug includeExceptionDetailInFaults="True" />
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
          <serviceThrottling maxConcurrentCalls="10000" maxConcurrentSessions="10000">    
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
          <serviceCredentials>
            <userNameAuthentication 
              userNamePasswordValidationMode="Custom" 
              customUserNamePasswordValidatorType="MYAPPHost.Authenticate, MYAPPHost"/>
          </serviceCredentials>         
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="OverAllEndPointBehavior" />
      </endpointBehaviors>
    </behaviors>        
    <bindings>
      <netTcpBinding>
        <binding name="ServiceTCPEndPointBinding" maxBufferSize="2147483647">    
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647" />
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" />
            <message clientCredentialType="UserName" algorithmSuite="TripleDes"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>        
    <services>
      <service behaviorConfiguration="OverAllServiceBehavior"
               name="MiddleWare.ServiceClasses.ServiceClass">    
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://127.0.0.1:15010/ServiceTCPEndPointMEX"/>            
          </baseAddresses>
        </host>    
        <endpoint address="net.tcp://127.0.0.1:15020/ServiceTCPEndPoint" contract="MiddleWare.ServiceContracts.IServiceContract" />           
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />    
      </service>
    </services>
  </system.serviceModel>
</configuration>

認証クラス:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IdentityModel.Selectors;

namespace MYAPPHost
{
    public class Authenticate : UserNamePasswordValidator
    {
        public override void Validate(string UserName, string Password)
        {
            if (!CheckFromDB(UserName,Password))
                throw new Exception("UNAUTHORIZED ACCESS!!!");
        }
    }
}

クライアント側では、WCF (SR) への参照を追加した後

SR.ServiceContractClient obj = new SR.ServiceContractClient("ServiceTCPEndPoint");
obj.ClientCredentials.UserName.UserName = "User1";
obj.ClientCredentials.UserName.Password = "Password1";
int I = obj.Add(1, 2);

資格情報が提供されていない場合、メッセージ セキュリティ トークン エラーがスローされます。間違った資格情報UNAUTHORIZED ACCESSが発生します。

于 2012-01-19T06:14:25.413 に答える