如何在 WCF 调用的服务端获取用户名和密码?

发布于 2024-10-19 20:09:24 字数 500 浏览 5 评论 0原文

当我使用以下代码在客户端提供凭据时:

myChannelFactory.Credentials.UserName.UserName = "username";
myChannelFactory.Credentials.UserName.Password = "password";

然后在服务器端,我看到这些凭据可用于

operationContext.IncomingMessageHeaders[1]

但是是否有更方便的方法来获取用户名和密码?我在 中看到的所有内容OperationContext 是属性和非类型化列表的混乱,我找不到任何表明我可以在哪里获得它的东西。

When I supply credentials at client with following code:

myChannelFactory.Credentials.UserName.UserName = "username";
myChannelFactory.Credentials.UserName.Password = "password";

Then on server side I see that these credentials are available in

operationContext.IncomingMessageHeaders[1]

However is there any more convenenient method to get the UserName and password? All I see in OperationContext is chaos of properties and untyped lists and I cant find anything that indicates where I can get this.

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

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

发布评论

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

评论(2

长梦不多时 2024-10-26 20:09:24

您可以使用静态当前 ServiceSecurityContext 上的属性 class 来获取正在调用的操作的当前 ServiceSecurityContext

然后,您可以使用 PrimaryIdentity属性,以便通过传入的凭据获取用户的身份。

但是,它不会(也不应该)暴露密码。如果您确实需要密码,那么您将必须下拉到消息级别并检查标头,如您所见。

You can use the static Current property on the ServiceSecurityContext class to get the current ServiceSecurityContext for the operation that is being called.

You can then use the PrimaryIdentity property in order to get the identity of the user with the credentials passed in.

However, it will not (nor should it), expose the password. If you truly need the password, then you will have to drop down to the message level and inspect the headers, as you've seen.

离笑几人歌 2024-10-26 20:09:24

这完全取决于您使用的绑定,并且没有通用答案。

例如,如果您使用 NetNamedPipeBinding,

myChannelFactory.Credentials.UserName.UserName = "username";
myChannelFactory.Credentials.UserName.Password = "password"; 

您是否在浪费时间:客户端绑定不会对此数据执行任何操作,它不会出现在消息中,并且在服务端根本无法访问它。

仅当配置了指定使用用户名/密码凭据的安全选项时,绑定才会消耗此数据。执行此操作的所有标准绑定都将使用凭据进行身份验证,然后结果将通过 ServiceSecurityContext 显示在服务中,如 casperOne 所示,并且不会包含密码数据。

为了支持身份验证,数据必须携带在消息头中的某处。确切的地点和形式将再次取决于绑定。不要以为您总能在 operationContext.IncomingMessageHeaders[1] 中找到它们。

编辑:
您也许能够构建一个自定义绑定,为您提供所需的内容。

CustomBinding binding = new CustomBinding( ... );
binding.Elements.Insert(1, 
  SecurityBindingElement.CreateUserNameOverTransportBindingElement());

在服务端,提供一个 UserNamePasswordValidator 并配置如下凭证:

serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = 
  System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
servicehost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = 
  new MyUserNamePasswordValidator();

然后,用户名和密码将被传递到 MyUserNamePasswordValidatorValidate 方法>。

警告:除非您使用安全传输,否则这不是安全身份验证机制,因为凭据在消息标头中以明文形式发送。

This is entirely dependent on the binding you are using, and there is no general answer.

For example, if you use the NetNamedPipeBinding and do

myChannelFactory.Credentials.UserName.UserName = "username";
myChannelFactory.Credentials.UserName.Password = "password"; 

you are wasting your time: the client side binding will do nothing with this data, it won't be in the message, and it won't be accessible at all on the service side.

The binding will only consume this data if it is configured with security options which specify the use of username/password credentials. All the standard bindings which do so will use the credentials for authentication, the results of which will then surface in the service via the ServiceSecurityContext as casperOne indicated, and won't include the Password data.

In order to support authentication, the data must be carried somewhere in the message headers. Exactly where and in what form will again be binding-dependent. Don't assume that you'll always find them in operationContext.IncomingMessageHeaders[1].

EDIT:
You may be able to construct a custom binding which gives you what you are looking for.

CustomBinding binding = new CustomBinding( ... );
binding.Elements.Insert(1, 
  SecurityBindingElement.CreateUserNameOverTransportBindingElement());

On the service side, provide a UserNamePasswordValidator and configure the credentials like this:

serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = 
  System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
servicehost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = 
  new MyUserNamePasswordValidator();

The user name and password will then be delivered to the Validate method of MyUserNamePasswordValidator.

WARNING: This is not a secure authentication mechanism unless you are using a secure transport, as the credentials are sent in clear in the message header.

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