私はWCF開発にかなり慣れておらず、フレームワークの学習中にいくつかの問題に遭遇しました。RESTとSOAPの両方をサポートする必要があるサービスAPIがあります。これまでのところ、これは特にWCF4とルーティングを使用して簡単に実装できます。
私は現在承認に取り組んでおり、「ApiKeyAuthorizationManager」と「ApiKeyAndTokenAuthorizationManager」という2つの新しいマネージャークラスを作成することで、AuthorizationManagerを拡張することができました。
私のサービスのほとんどは、ApiKey and Token(GUIDS)が存在する必要があります。最初に認証するときは、トークンを受け取るために有効なApiKeyとパスワードが必要です。
これまでのところ、承認マネージャーがクエリ文字列を調べてApiKeyやTokenを取得しているため、RESTは完全に機能しています。
したがって、たとえば、サービスURIは次のようになります。* http://api.domain.com/Service/Operation/ {someVariableValue}?ApiKey = GUID&Token = GUID
私の問題は、SOAPサービス呼び出しの承認にあります。私は少し調査を行い、実装する前に正しいことを確認したかったいくつかの結論に達しました。
カスタムクレデンシャルを使用してSOAPを承認するには、次のことを行う必要があります。
- カスタムサービストークンの作成(MSDN)
- カスタムSecurityTokenProvider、SecurityTokenAuthenticator、およびSecurityTokenSerializerを作成してWCFを拡張する(MSDN)
- カスタムAuthorizationPoliciesを作成してWCFを拡張する(MSDN)
私はこれについて正しい方向に進んでいますか?私のシナリオに合わせるには、これらすべての手順が必要ですか?2つのGUIDで構成されるクレデンシャルを検証するためのカスタマイズが非常に多いようです。
ありがとう!
[編集#1]
これは非常に難しい作業でした。カスタムクレデンシャルとセキュリティトークンはほとんど文書化されていません。質の高いブログ投稿自体を見つけることは、ほぼ不可能であることが証明されています。私はプラグを抜き続けており、実用的な解決策を手に入れるのにとても近いです。この投稿で説明されているのと同じ障害にぶつかったこともあります。
サービスにアクセスしてwsdlまたはmexを検出しようとすると、次のエラーが発生します。
The service encountered an error.
An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a policy export extension.
Extension: System.ServiceModel.Channels.SymmetricSecurityBindingElement
Error: Specified argument was out of the range of valid values.
Parameter name: parameters ----> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: parameters
at System.ServiceModel.Security.WSSecurityPolicy.CreateTokenAssertion(MetadataExporter exporter, SecurityTokenParameters parameters, Boolean isOptional)
at System.ServiceModel.Security.WSSecurityPolicy.CreateWsspSignedSupportingTokensAssertion(MetadataExporter exporter, Collection`1 signed, Collection`1 signedEncrypted, Collection`1 optionalSigned, Collection`1 optionalSignedEncrypted)
at System.ServiceModel.Security.WSSecurityPolicy.CreateWsspSupportingTokensAssertion(MetadataExporter exporter, Collection`1 signed, Collection`1 signedEncrypted, Collection`1 endorsing, Collection`1 signedEndorsing, Collection`1 optionalSigned, Collection`1 optionalSignedEncrypted, Collection`1 optionalEndorsing, Collection`1 optionalSignedEndorsing, AddressingVersion addressingVersion)
at System.ServiceModel.Security.WSSecurityPolicy.CreateWsspSupportingTokensAssertion(MetadataExporter exporter, Collection`1 signed, Collection`1 signedEncrypted, Collection`1 endorsing, Collection`1 signedEndorsing, Collection`1 optionalSigned, Collection`1 optionalSignedEncrypted, Collection`1 optionalEndorsing, Collection`1 optionalSignedEndorsing)
at System.ServiceModel.Channels.SecurityBindingElement.ExportSymmetricSecurityBindingElement(SymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)
at System.ServiceModel.Channels.SecurityBindingElement.ExportPolicy(MetadataExporter exporter, PolicyConversionContext context)
at System.ServiceModel.Description.MetadataExporter.ExportPolicy(ServiceEndpoint endpoint)
--- End of inner ExceptionDetail stack trace ---
at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()
at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension)
at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData()
at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleDocumentationRequest(Message httpGetRequest, String[] queries, Message& replyMessage)
at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest)
at SyncInvokeGet(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
何がこれを引き起こしているのかについて何か考えがあれば、私はいくつかの助けが欲しいです。
[編集#2]
Microsoftは、カスタムクレデンシャル/トークンのwsdlサポートを許可する方法を示すためにサンプルを更新したくないようです。 ここを参照してください。誰かがこれを機能させる方法を知っていますか?フレームワークを拡張する方法のドキュメントがない場合、フレームワークを拡張可能にすることのポイントは何ですか?!?
[編集#3]
以下の私のコメントで述べられているように...私は、UserNameSecurityTokenを使用してTransportWithMessageCredentialが正常に機能しています。残念ながら、私が計画したいくつかのより高度な機能を実装するとき、私のサービスはカスタムトークンを必要とすることになります。
私が答えとして探しているのは次のとおりです。
WSDLサポートでカスタムサービスのクレデンシャルとトークンをサポートするにはどうすればよいですか?
現在、Microsoftの例に従って、カスタムクレデンシャルは、ChannelFactoryを使用し、クライアントでカスタムバインディングを作成することによってのみ使用できます。私はむしろそれに対処したくありません。
この質問に答えられないままの場合、私はその恩恵を増やし続けます。これがすべて機能するようになったらすぐに、カスタムセキュリティソリューションの作成に必要なすべての手順に関するブログチュートリアルを作成します。