11

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

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

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

有任何想法吗?

4

2 回答 2

13

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

编辑:

在更仔细地重新阅读了这个问题之后(以及在 Ariel 的评论之后),我想撤回上述建议。WCF 身份验证服务不会为这种情况添加太多内容。

我没有在 WCF 和 ASP.NET 之间这样做,但是我已经将 ASP.NET 应用程序配置为共享表单经过身份验证的用户,也许我可以在某些方面提供帮助。

为确保两个应用程序可以以相同的方式加密/解密表单身份验证 cookie,您应该为两个应用程序配置<machineKey>元素(在 web.config 或 machine.config 中,具体取决于您是要在机器级别还是在应用程序级别执行此操作)。您应该查看validationvalidationKeydecryption属性decryptionKey

确保<forms>两个 web.config 文件中的元素配置相似。特别是name,pathdomain属性。

这很可能仅适用于传入/传出 Web 浏览器的 cookie(但在这种情况下可能有用):要允许在网站www.foo.combar.foo.com之间传递 cookie,您需要配置forms元素如下允许在一个站点上设置 cookie 并成功传递给另一个站点:

<forms ... domain=".foo.com" ... />

将 cookie 传递给 WCF 服务可能是一个棘手的问题。我对 WCF 不是很有经验,所以我改编了来自 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).

我不知道这是否可行,但很想听听是否可行!

于 2009-07-06T14:35:46.853 回答
4

如果您在经过身份验证的 IIS 站点中托管 WCF 服务,这很简单。

通过将以下内容添加到 web.config 中的 system.ServiceModel 部分来启用兼容性

<system.serviceModel>  
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
</system.serviceModel>

然后用以下内容装饰您希望接受 cookie 的每个服务

[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

现在 HttpContext.Current.User.Identity 对象将被正确填充,您还可以使用 PrinciplePermission 要求来限制角色或特定用户的访问。

于 2009-07-06T21:19:19.283 回答