WCF + 用户凭证

发布于 2024-07-27 12:39:09 字数 346 浏览 7 评论 0原文

我正在开发 Silverlight v3 Web 应用程序,我希望安全地访问我用来获取数据的 WCF 服务。 我目前的 WCF 工作得很好,但它不需要任何用户凭据。

我对 WCF 这方面的经验不是很丰富,所以我的第一个想法是向我的每个服务操作添加用户名和密码参数。 我遇到的问题是,这将需要大量冗余代码,并且用户名和密码将以纯文本形式通过网络传输。

我想要的是一种在创建服务代理后立即在客户端预先指定凭据的方法(我正在使用从“添加服务引用”自动生成的代理)。

在谷歌搜索解决方案时,我只能找到与我的第一个想法类似的解决方案(使用用户名/密码参数)。 有人可以指出我正确的方向吗?

谢谢!

I am working on a Silverlight v3 web app and I would like to secure access to the WCF service I am using to fetch my data. I currently have the WCF working just fine, but it doesn't require any user credentials.

I'm not very experienced with this aspect of WCF, so my first idea was to add username and password parameters to each of my service's operations. The problem I have with this is that this would require a lot of redundant code, and the fact that the username and password would be transferred over the wire in plain text.

What I would like is a way to specify the credentials upfront on the client side right after I create my service proxy (I am using the proxy autogenerated from "Add Service Reference").

Upon googling for a solution to this, I could only find solutions that similar to my first idea (using username/password parameters). Could someone please point me in the right direction?

Thanks!

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

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

发布评论

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

评论(3

z祗昰~ 2024-08-03 12:39:09

这些用户名和密码从哪里来? 如果您的网站已经实现了表单身份验证,那么您可以绕过自己设置凭据并使用表单身份验证 cookie。 如果您的用户已登录,则 cookie 将随 Web 服务调用一起传输。 为了在另一面阅读它,您需要进行一些更改。

首先,您需要在 system.ServiceModel 部分中为 WCF 启用 ASP.NET 兼容模式:

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

完成后,对于您想要了解 ASP.NET cookie 的每个服务方法,将 [AspNetCompatibilityRequirements] 属性添加到您的服务类

[ServiceContract]
[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ExampleService
{
}

中。方法您可以访问 HttpContext.Current.User.Identity 对象来发现用户的身份。

如果您只希望经过身份验证的用户调用某些方法,那么您可以使用PrincipalPermission,因此

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
public string Echo()

如果您使用ASP.NET的角色提供程序,那么这些方法也会被填充,然后您可以在方法上使用PrincipalPermission来限制它们特定角色的成员:

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role="Administators")]
public string NukeTheSiteFromOrbit()

这显然也适用于 Silverlight2。

Where are these usernames and passwords coming from? If your web site already implements Forms authentication then you can bypass setting credentials yourself and use the forms authentication cookie. If your users are logged in then the cookie will travel with the web service call. In order to read it on the other side you need to make a couple of changes.

First you need to enable ASP.NET compatibility mode for WCF in the system.ServiceModel section:

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

Once that is done then for each service method you want to understand the ASP.NET cookie add the [AspNetCompatibilityRequirements] attribute to your service class

[ServiceContract]
[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ExampleService
{
}

Now within each method you can access the HttpContext.Current.User.Identity object to discover the user's identity.

If you only want certain methods to be called by authenticated users then you can use a PrincipalPermission thus

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
public string Echo()

As a bonus if you're using ASP.NET's role provider then those will also be populated and you can then use a PrincipalPermission on methods to limit them to members of a particular role:

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role="Administators")]
public string NukeTheSiteFromOrbit()

And this works in Silverlight2 as well obviously.

对岸观火 2024-08-03 12:39:09

不要自己动手并添加显式参数 - 这确实是太多的工作!

查看 WCF 安全功能 - 其中有很多可用! 例如,您可以保护消息并在消息中包含凭据 - 所有这些都是开箱即用的,无需您进行额外的编码!

查看 Michele Leroux Bustamante 撰写的关于 WCF 安全性的精彩文章: http://www.devx.com /codemag/Article/33342

在您的情况下,我建议使用用户名凭据进行消息安全 - 您需要在两端进行配置:

服务器端:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="YourService">
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
  </service>
</services>

并且您需要申请在客户端进行相同的设置:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
</client>

现在您的服务器和客户端就安全性达成一致 - 在客户端上,您将指定要使用的用户名和密码,如下所示:

YourServiceClient client = new YourServiceClient();

client.ClientCredentials.UserName.UserName = "your user name";
client.ClientCredentials.UserName.Password = "top$secret";

在服务器端,您需要设置如何这些用户凭据正在被验证 - 通常是针对 Windows 域 (Active Directory) 或针对 ASP.NET 成员资格提供程序模型。 无论如何,如果无法根据您定义的存储验证用户凭据,则调用将被拒绝。

希望这会有所帮助 - 安全性是 WCF 中的一个大主题,并且有很多很多选项 - 它可能有点令人畏惧,但最终,通常它确实有意义! :-)

马克

Don't roll your own and add explicit parameters - that is indeed way too much work!

Check out the WCF security features - plenty of them available! You can e.g. secure the message and include credentials inside the message - all out of the box, no extra coding on your side required!

Check out this excellent article on WCF security by Michele Leroux Bustamante: http://www.devx.com/codemag/Article/33342

In your case, I'd suggest message security with user name credentials - you need to configure this on both ends:

Server-side:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="YourService">
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
  </service>
</services>

And you need to apply the same settings on the client side:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
</client>

Now your server and client agree on the security - on the client, you'd then specify the user name and password to use like this:

YourServiceClient client = new YourServiceClient();

client.ClientCredentials.UserName.UserName = "your user name";
client.ClientCredentials.UserName.Password = "top$secret";

On the server side, you'll need to set up how these user credentials are being validated - typically either against a Windows domain (Active Directory), or against the ASP.NET membership provider model. In any case, if the user credentials cannot be verified against that store you define, the call will be rejected.

Hope this helps a bit - security is a big topic in WCF and has lots and lots of options - it can be a bit daunting, but in the end, usually it does make sense! :-)

Marc

深白境迁sunset 2024-08-03 12:39:09

您可以传入某种身份验证对象并使用 WCF 在消息级别对其进行加密。 然后可以使用 C# 方面 (http://www.postsharp.org/) 来避免冗余逻辑。 这是一种非常干净的处理方式。

you can pass in some sort of authentication object and encrypt it at the message level with WCF. C# aspects (http://www.postsharp.org/) can then be used to avoid redundant logic. Its a very clean way of handling it.

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