5

我对 WCF 开发相当陌生,并且在学习框架时遇到了一些问题。我有一个必须同时支持 REST 和 SOAP 的服务 api。到目前为止,这很容易实现,尤其是使用 WCF4 和路由。

我目前正在研究授权,并通过创建两个新的管理器类来扩展 AuthorizationManager:“ApiKeyAuthorizationManager”和“ApiKeyAndTokenAuthorizationManager”

我的大部分服务都需要有 ApiKey 和 Token (GUIDS);最初进行身份验证时,您只需要一个有效的 ApiKey 和密码即可接收 Token。

到目前为止,REST 运行良好,因为授权管理器查看查询字符串以获取 ApiKey 和/或令牌。

例如,服务 uri 看起来像: * http://api.domain.com/Service/Operation/ {someVariableValue}?ApiKey=GUID&Token=GUID

我的问题现在与授权 SOAP 服务调用有关。我做了一些研究,并得出了一些我想在实施之前验证是否正确的结论。

为了使用自定义凭据授权 SOAP,我应该:

  1. 创建自定义服务令牌 ( MSDN )
  2. 通过创建自定义 SecurityTokenProvider、SecurityTokenAuthenticator 和 SecurityTokenSerializer ( MSDN )来扩展 WCF
  3. 通过创建自定义 AuthorizationPolicies ( MSDN )扩展 WCF

我在正确的轨道上吗?所有这些步骤都需要适合我的场景吗?似乎只是为了验证由两个 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]

微软似乎不想更新他们的示例来展示如何允许 wsdl 支持自定义凭据/令牌。 见这里。任何人都知道如何让这个工作?如果没有文档如何扩展它,那么使框架可扩展的意义何在?!?


[编辑#3]

正如我在下面的评论中所述......我使用 UserNameSecurityToken 让 TransportWithMessageCredential 工作得很好。不幸的是,当需要实现我计划的一些更高级的功能时,我的服务最终将需要自定义令牌。

我正在寻找的答案是:

如何通过WSDL 支持来支持自定义服务凭证和令牌?

目前,按照 Microsoft 的示例,您只能通过使用 ChannelFactory 并在客户端上创建自定义绑定来使用自定义凭据。我宁愿不处理那个。

如果这个问题仍未得到解答,我将继续增加赏金。一旦我能完成这一切,我将写一篇博客教程,介绍创建自定义安全解决方案所需的所有步骤。

4

1 回答 1

5

我建议您查看 Windows Identity Foundation,并朝着基于声明的安全/联合的方向发展。此模型更好地支持自定义凭据,因为它们只是一组不同的声明。

于 2010-11-25T09:11:55.257 回答