WCF - 自定义凭据和安全令牌
我对 WCF 开发相当陌生,在学习该框架时遇到了一些问题。我有一个服务 API,它必须同时支持 REST 和 REST。肥皂。到目前为止,这很容易实现,尤其是使用 WCF4 和路由。
我目前正在研究授权,并通过创建两个新的管理器类来扩展 AuthorizationManager:“ApiKeyAuthorizationManager”和“ApiKeyAuthorizationManager”。 “ApiKeyAndTokenAuthorizationManager”
我的大多数服务都需要 ApiKey 和令牌 (GUIDS);初始身份验证时,您只需要有效的 ApiKey 和密码即可接收 Token。
到目前为止,REST 工作得很好,因为授权管理器会通过查询字符串来获取 ApiKey 和/或令牌。
例如,服务 uri 如下所示: *http://api.domain.com/Service/Operation/{someVariableValue}? ApiKey=GUID&Token=GUID
我现在的问题是授权 SOAP 服务调用。我做了一些研究,并得出了一些结论,我想在实施之前验证其正确性。
为了使用自定义凭据授权 SOAP,我应该:
- 创建自定义服务令牌 (MSDN< /a>)
- 通过创建自定义 SecurityTokenProvider、SecurityTokenAuthenticator 和 SecurityTokenSerializer 来扩展 WCF (MSDN )
- 通过创建自定义授权策略来扩展 WCF (MSDN)
我的方向正确吗?所有这些步骤都需要适合我的场景吗?似乎只是为了验证由两个 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 并在客户端上创建自定义绑定来使用自定义凭据。我宁愿不处理这个问题。
如果这个问题仍然没有答案,我将继续提高赏金。一旦我能让这一切正常工作,我就会写一篇博客教程,介绍创建自定义安全解决方案所需的所有步骤。
I'm fairly new to WCF development and have run into a couple problems whilst learning the framework. I have a service api which must support both REST & SOAP. So far this has been easy to implement especially with WCF4 and routing.
I am currently working on authorization and have managed to extend AuthorizationManager by creating two new manager classes: "ApiKeyAuthorizationManager" & "ApiKeyAndTokenAuthorizationManager"
Most of my services will require an ApiKey and Token (GUIDS) to be present; when initially authenticating, you simply need a valid ApiKey and password to receive a Token.
So far REST is working perfectly as the Authorization managers look to the query string to get ApiKey and/or Token.
So for example a service uri would look like:
*http://api.domain.com/Service/Operation/{someVariableValue}?ApiKey=GUID&Token=GUID
My problem now comes with authorizing SOAP service calls. I've done a little bit of research and have come to a few conclusions I wanted to verify are correct before implementing.
In order to authorize SOAP with custom credentials I should:
- Create custom service token (MSDN)
- Extend WCF by creating a custom SecurityTokenProvider, SecurityTokenAuthenticator, and SecurityTokenSerializer (MSDN)
- Extend WCF by creating custom AuthorizationPolicies (MSDN)
Am I on the right track for this? Are all these steps needed to fit my scenario? Seems like so much customization for just verifying a credential made up of two GUIDs.
Thanks!
[EDIT #1]
This has been a very difficult task. Custom credentials and security tokens is nearly undocumented. Finding quality blog posts itself has proven near impossible. I've kept plugging away and am so close to have a working solution. I've even hit the same road blocks as described in this post.
When I try to access my service to uncover the wsdl or mex I receive this error:
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)
If you have any idea what might be causing this I'd love some help.
[EDIT #2]
It seems Microsoft doesn't want to update their samples to show how to allow wsdl support for custom credentials / tokens. See here.
Anyone have an idea how to get this working? What's the point of making a framework extensible if there's no documentation how to extend it?!?
[EDIT #3]
As stated in my comment below...
I have TransportWithMessageCredential working just fine using UserNameSecurityToken. Unfortunately, my services will end up requiring custom tokens when it's time to implement some more advanced features that I have planned.
What I'm looking for as an answer would be:
How to support custom service credentials and tokens with WSDL support?
Currently, following Microsoft's examples, you can only use custom credentials by using ChannelFactory and creating a custom binding on the client. I would rather not deal with that.
If this question remains unanswered, I'll keep upping the bounty. As soon as I can get this all working I'll write up a blog tutorial on all the steps required to creating a custom security solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议您关注 Windows Identity Foundation,并朝着基于声明的安全/联合的方向发展。该模型更好地支持自定义凭据,因为它们只是一组不同的声明。
I would advise you look to Windows Identity Foundation, and move in the direction of claim based security/federation. This model supports custom credentials much better as they are just a different set of claims.