将 FormsAuthentication cookie 传递给 WCF 服务

发布于 2024-07-26 03:42:27 字数 428 浏览 4 评论 0原文

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

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

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

有任何想法吗?

I have a website that talks to a remote WCF web service. Both use the same custom FormsAuthentication Provider. I would like to authenticate with the WCF service impersonating the user currently logged in the site. I already did this manually, using UserName client credentials but I need to know the user password.
So, what works so fart is this: an authenticated user makes a request, I create a Service Client and set his credentials:

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

But what I really want is to pass the FormsAuthentication cookie directly, because I don't want to store the user password.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

彩虹直至黑白 2024-08-02 03:42:27

听起来您正在寻找 Windows Communication Foundation 身份验证服务

编辑:

在更仔细地重新阅读问题之后(以及在 Ariel 的评论之后),我想撤回上述建议。 WCF 身份验证服务不会给这种情况带来太多影响。

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

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

确保两个 web.config 文件中的 元素配置类似。 特别是 namepathdomain 属性。

这可能仅适用于传入/传出网络浏览器的 cookie(但在这种情况下可能有用):允许在网站 www.foo.com之间传递 cookie bar.foo.com 您可以按如下方式配置 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)

我不知道这是否有效,但很想听听是否有效!

It sounds like you're looking for the Windows Communication Foundation Authentication Service.

EDIT:

After re-reading the question more carefully (and after Ariel's comment) I'd like to retract the above suggestion. The WCF Authentication Service won't add much to this scenario.

I haven't done this between WCF and ASP.NET, however I have configured ASP.NET applications to share forms authenticated users, perhaps I can help in some way.

To ensure that both applications can encrypt/decrypt the forms authentication cookie in the same way you should configure the <machineKey> element for both applications (in web.config or machine.config depending on whether you want to do this at the machine or application level). You should look at the validation, validationKey, decryption and decryptionKey attributes.

Ensure that your <forms> elements in both web.config files are configured similarly. Specifically the name, path and domain attributes.

It's likely that this only applies to cookies passed to/from a web browser (but may be useful in this case): To allow cookies to be passed between the websites www.foo.com and bar.foo.com you would configure the forms element as follows to allow cookies to be set on one site and successfully passed to the other:

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

Passing the cookie to the WCF service is likely to be the tricky bit. I'm not very experienced with WCF, so 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();
} 

If you're hosting WCF within IIS (and not self-hosting) you can pass the WCF request through the ASP.NET processing pipeline by setting

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

If you're self hosting you could examine the request headers using the incoming message's properties in OperationContext.Current.IncomingMessageProperties and get the forms authentication cookie value and decrypt it using FormsAuthentication.Decrypt(string).

I have no idea whether any of this would work, but would love to hear if it does!

酸甜透明夹心 2024-08-02 03:42:27

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

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

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

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

[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

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

It's simple enough to do if you host the WCF service within the authenticated IIS site.

Enable compatibility by adding the following to your system.ServiceModel section in your web.config

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

Then decorate each service you wish to accept the cookie with the following

[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

Now the HttpContext.Current.User.Identity object will be correctly populated and you can also use PrinciplePermission demands to limit access by role or to particular users.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文