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

6
当我在客户端使用以下代码提供凭据时:
myChannelFactory.Credentials.UserName.UserName = "username";
myChannelFactory.Credentials.UserName.Password = "password";

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

operationContext.IncomingMessageHeaders[1]

然而,有没有更方便的方法来获取用户名和密码?我在OperationContext中看到的只是一堆属性和未分类的列表混乱,我找不到任何指示我可以获取它们的地方。

你为什么想要这个?你是想执行额外的身份验证吗? - McKay
2个回答

3
您可以使用ServiceSecurityContext上的静态Current属性获取当前调用操作的ServiceSecurityContext
然后,您可以使用PrimaryIdentity属性来获取传递凭据的用户的标识。
但是,它不会(也不应该)公开密码。如果您真正需要密码,则必须降至消息级别并检查头文件,就像您所看到的那样。

不,这是另外一回事。在SecurityCServiceContext中包含用户的WINDOWS凭据。那完全不同于我在通道工厂上设置的凭据。 - Filip Nguyen
1
@Kalaz:不,那不是真的,WindowsIdentity属性提供的是WINDOWS凭据。PrimaryIdentity是完全不同的东西。 - casperOne

2

这完全取决于您使用的绑定方式,因此没有通用答案。

例如,如果您使用NetNamedPipeBinding并执行以下操作:

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

你正在浪费时间:客户端绑定不会对这些数据进行任何操作,它不会出现在消息中,服务端也无法访问。只有当绑定配置了指定使用用户名/密码凭据的安全选项时,绑定才会消耗这些数据。所有标准绑定都将使用凭据进行身份验证,其结果将通过ServiceSecurityContext在服务中显示,但不包括密码数据。
为了支持身份验证,数据必须被携带到消息头中的某个位置。具体在哪里以及以什么形式取决于绑定。不要假设你总能在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方法。

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


嗯,是的,没错。那么我能否配置自定义绑定,以便在代码中的一个地方同时拥有服务器端的两个信息(用户名/密码和域凭据信息)?我需要这两个信息在同一位置,以便使用有效的那个。 - Filip Nguyen
@Kalaz:请看我回答的编辑部分。您可以进行自定义用户名/密码验证。但是,不确定这是否完全符合您所需,因为您还提到了域凭据。 - Chris Dickson
我会在本周末尝试您的建议。为了消除对域凭据的困惑:我正在寻找一种通过用户在域中的成员身份验证 + 我的自定义登录/密码的方式。实际上,我将使用域成员身份验证,以便应用程序表现出单一登录的方式。然而,当域信息不可用时,我将使用自定义凭据。如果您的解决方案产生具有域信息的可访问SecurityContext,那就是我要找的东西。 - Filip Nguyen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接