将FormsAuthentication cookie传递给WCF服务

时间:2009-07-06 14:25:39

标签: asp.net wcf forms-authentication wcf-security

我有一个与远程WCF Web服务对话的网站。两者都使用相同的自定义FormsAuthentication Provider。我想通过模拟当前登录站点的用户的WCF服务进行身份验证。我已经使用UserName客户端凭据手动执行此操作,但我需要知道用户密码。 那么,最有效的是:经过身份验证的用户发出请求,我创建了一个服务客户端并设置了他的凭据:

serviceClient.ClientCredentials.UserName.UserName = username;
serviceClient.ClientCredentials.UserName.Password = password;

但我真正想要的是直接传递FormsAuthentication cookie,因为我不想存储用户密码。

有什么想法吗?

2 个答案:

答案 0 :(得分:13)

听起来你正在寻找Windows Communication Foundation Authentication Service

修改

在仔细阅读问题后(以及在Ariel的评论之后),我想撤回上述建议。 WCF身份验证服务不会对此方案添加太多内容。

我没有在WCF和ASP.NET之间完成此操作,但是我已将ASP.NET应用程序配置为共享经过身份验证的用户,也许我可以在某种程度上提供帮助。

确保两个应用程序都可以加密/解密表单身份验证cookie,方法与configure the <machineKey> element两个应用程序相同(在web.config或machine.config中,具体取决于您是否要在计算机上执行此操作)或应用程序级别)。您应该查看validationvalidationKeydecryptiondecryptionKey属性。

确保两个web.config文件中的<forms>元素的配置类似。具体而言是namepathdomain属性。

这可能仅适用于传入/传出网络浏览器的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要求来限制角色或特定用户的访问。