我有一个与远程WCF Web服务对话的网站。两者都使用相同的自定义FormsAuthentication Provider。我想通过模拟当前登录站点的用户的WCF服务进行身份验证。我已经使用UserName客户端凭据手动执行此操作,但我需要知道用户密码。 那么,最有效的是:经过身份验证的用户发出请求,我创建了一个服务客户端并设置了他的凭据:
serviceClient.ClientCredentials.UserName.UserName = username;
serviceClient.ClientCredentials.UserName.Password = password;
但我真正想要的是直接传递FormsAuthentication cookie,因为我不想存储用户密码。
有什么想法吗?
答案 0 :(得分:13)
听起来你正在寻找Windows Communication Foundation Authentication Service。
修改强>
在仔细阅读问题后(以及在Ariel的评论之后),我想撤回上述建议。 WCF身份验证服务不会对此方案添加太多内容。
我没有在WCF和ASP.NET之间完成此操作,但是我已将ASP.NET应用程序配置为共享经过身份验证的用户,也许我可以在某种程度上提供帮助。
确保两个应用程序都可以加密/解密表单身份验证cookie,方法与configure the <machineKey>
element两个应用程序相同(在web.config或machine.config中,具体取决于您是否要在计算机上执行此操作)或应用程序级别)。您应该查看validation
,validationKey
,decryption
和decryptionKey
属性。
确保两个web.config文件中的<forms>
元素的配置类似。具体而言是name
,path
和domain
属性。
这可能仅适用于传入/传出网络浏览器的cookie(但在这种情况下可能很有用):允许在网站之间传递cookie www.foo.com 和 bar.foo.com 您可以按如下方式配置forms
元素,以允许在一个站点上设置cookie并成功传递给另一个站点:
<forms ... domain=".foo.com" ... />
将cookie传递给WCF服务可能是一个棘手的问题。我对WCF不是很有经验,所以I've adapted code from kennyw.com:
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add(HttpRequestHeader.Cookie, "<Forms Authentication Cookie>");
using (OperationContextScope scope = new OperationContextScope(serviceClient.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
serviceClient.MethodName();
}
如果您在IIS中托管WCF(而不是自托管),则可以通过设置
来通过ASP.NET处理管道传递WCF请求<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" ... />
</system.serviceModel>
如果您是自托管,则可以使用OperationContext.Current.IncomingMessageProperties
中的传入邮件属性检查请求标头,并获取表单身份验证Cookie值并使用FormsAuthentication.Decrypt(string)
对其进行解密。
我不知道这是否有效,但是如果有的话,我很乐意听到!
答案 1 :(得分:4)
如果您在经过身份验证的IIS站点中托管WCF服务,那么这很简单。
通过将以下内容添加到web.config中的system.ServiceModel部分来启用兼容性
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
然后使用以下
装饰您希望接受cookie的每个服务[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
现在将正确填充HttpContext.Current.User.Identity对象,您还可以使用PrinciplePermission要求来限制角色或特定用户的访问。