私は ASP.net/WinForms アプリを作成した経験があり、簡単なタスク マネージャー プロジェクトを作成して WCF を学習したいと考えています。
受信したテキスト ブロックをお読みいただき、ありがとうございます。私の問題は、実際のコーディングの問題ではなく、設計の問題です。
私の目標は次のとおりです。
- タスク/todo リストの管理を目的とする Web サービスを (WCF を使用して) 作成する
- Web サービスにより、ユーザーはアカウントの登録、新しい To Do リストの作成、To Do リストの他のユーザーとの共有などを行うことができます。
- Web サービスが機能し、すべてが実装された後、ASP.NET Web サイトをその上に重ねて、バックエンドに Web サービスを使用できるようにしたいと考えています。
現時点では、次のものがあります。
- Web サービスをホストする 1 つのコンソール アプリケーション
- Web サービスへの呼び出しに使用される 1 つのコンソール アプリケーション (クライアント) (この方法で Web サービスをテストします)
Web サービス アプリケーションには、次の構成ファイルがあります (問題なく貼り付けられていることを願っています)。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Tasker_Server.Properties.Settings.TaskerConnectionString"
connectionString="Data Source=PROPHET\SQLEXPRESS;Initial Catalog=Tasker;Persist Security Info=True;User ID=sa;Password=stf"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.serviceModel>
<services>
<service name="Tasker_Server.TaskerService" behaviorConfiguration="TaskerServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/TaskerTest/Service" />
</baseAddresses>
</host>
<endpoint name="login" address="username" binding="wsHttpBinding"
bindingConfiguration="Binding1"
contract="Tasker_Server.ITasker" />
<endpoint name="reg" address="reg" binding="wsHttpBinding"
bindingConfiguration="Binding2"
contract="Tasker_Server.Contracts.IRegister" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="Binding1" receiveTimeout="00:20:00">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
<binding name="Binding2">
<security mode="None">
<transport clientCredentialType="None" />
<message establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="TaskerServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Tasker_Server.CustomValidator, Tasker_Server" />
<serviceCertificate findValue="localhost"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
そして、次のように Web サービスを開始します。
ServiceHost selfHost = new ServiceHost(typeof(TaskerService));
try {
selfHost.Open();
Console.WriteLine("Service is up... (press <ENTER> to terminate)");
Console.ReadLine();
selfHost.Close();
}
catch (CommunicationException ce) {
Console.WriteLine("Exception: {0}", ce.Message);
Console.ReadLine();
selfHost.Abort();
}
現時点では、次の 2 つの契約しかありません。
[ServiceContract(Namespace="http://Tasker_Server")]
public interface ITasker {
[OperationContract]
string CheckCredentials(string username, string password);
}
と
[ServiceContract(Namespace="http://Tasker_Register")]
public interface IRegister {
[OperationContract]
string RegisterUser(string username, string password, string email);
}
私が達成しようとしたことは次のとおりです。
- 安全でないエンドポイントを提供します。クライアントはこれを呼び出してアカウントを登録できます。
- ユーザーが「ログイン」してすべての操作を呼び出すことができる、セキュリティで保護されたエンドポイントを提供します (カスタム UserNamePasswordValidator で UserName 認証を使用します)。
私のソフトウェアでは、これらの両方が現在機能しています。セキュリティで保護されていないエンドポイントを介して新しいアカウントを登録でき、クライアントで正しい ClientCredentials を提供することで、セキュリティで保護されたエンドポイントを呼び出すことができます。
私の質問は次のとおりです。
私が理解していることから、UserName 認証を使用することにより、クライアントが Web サービス メソッドを呼び出すたびに、カスタム バリデーターの Validation メソッドが呼び出されます (これは、DB クエリが毎回実行されて資格情報をチェックすることを意味します。セッションが期限切れになるまで 1 回ログインします)。このように物事を行うことに根本的に何か問題がありますか?
これを管理する別の方法を考えました (そして、ある意味で Web サイトがどのように機能するかをシミュレートします):
- 「ログイン」に似た操作にのみ、安全なエンドポイント (UserName 認証) を使用します。
- 資格情報が正しい場合は、新しい GUID を作成してメモリに保存し、ユーザー名とその GUID を関連付けます。
- その場合、すべての操作で UserName 認証は必要ありませんが、追加のパラメーター (GUID) があります。GUID がメモリ内にあり、ユーザーに関連付けられている場合、操作は許可されます。
- ログアウト操作は、メモリ内の GUID を破壊します。
- GUIDがクリアで送信されないように、これに加えてSSLを使用できると思います
- これは Web サービス セキュリティの目的に反するのでしょうか?
どの方法が良いでしょうか?なぜ?
更新:間違った構成ファイルを追加しました。Web サービスではなく、クライアントからのものでした。正しいものを追加しました。