使用自定义UserNamePasswordValidator校验凭据时,如何在WCF服务中获取SOAP请求的Envelope.Header.Security.UserNameToken.Username字段用户名?
在WCF中通过自定义UserNamePasswordValidator获取SOAP请求的用户名
嘿,这个问题我熟!在WCF里通过自定义UserNamePasswordValidator获取SOAP请求里的Envelope.Header.Security.UserNameToken.Username字段,其实不用手动去解析XML节点——WCF框架已经帮你把这个值提取好了,直接用就行,具体步骤如下:
1. 实现自定义UserNamePasswordValidator类
首先创建一个继承自System.IdentityModel.Selectors.UserNamePasswordValidator的自定义验证器,在它的Validate方法里,第一个参数就是你要找的Username字段值:
using System.IdentityModel.Selectors; using System.ServiceModel; using System; namespace YourNamespace { public class CustomUserValidator : UserNamePasswordValidator { public override void Validate(string userName, string password) { // 这里的userName参数就是SOAP头里的Envelope.Header.Security.UserNameToken.Username值 if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password)) { throw new FaultException("用户名或密码不能为空"); } // 这里写你的自定义校验逻辑,比如查询数据库验证合法性 if (!(userName.Equals("validUser", StringComparison.OrdinalIgnoreCase) && password == "correctPass")) { throw new FaultException("用户名或密码无效"); } } } }
2. 注册自定义验证器到WCF服务
接下来需要把这个自定义验证器配置到你的WCF服务中,有两种方式:
方式一:通过配置文件(App.config/Web.config)
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="YourServiceBehavior"> <serviceCredentials> <!-- 指定验证模式为自定义,并关联我们的验证器类 --> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="YourNamespace.CustomUserValidator, YourAssemblyName"/> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> <!-- 记得在service节点里引用这个behavior --> <services> <service name="YourNamespace.YourService" behaviorConfiguration="YourServiceBehavior"> <!-- 服务端点配置 --> <endpoint address="" binding="wsHttpBinding" contract="YourNamespace.IYourService"/> </service> </services> </system.serviceModel>
方式二:通过代码配置(适合动态场景)
如果是用代码初始化ServiceHost,可以这样注册:
using System.ServiceModel; using System.ServiceModel.Description; // 初始化服务宿主 ServiceHost serviceHost = new ServiceHost(typeof(YourNamespace.YourService)); // 获取或创建服务凭据行为 ServiceCredentials credentials = serviceHost.Description.Behaviors.Find<ServiceCredentials>(); if (credentials == null) { credentials = new ServiceCredentials(); serviceHost.Description.Behaviors.Add(credentials); } // 设置自定义验证器 credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserValidator(); // 启动服务 serviceHost.Open();
3. 额外:在服务操作方法中获取当前用户名
如果在你的服务接口方法里需要用到当前请求的用户名,还可以通过OperationContext直接获取:
public string GetCurrentUser() { // 从安全上下文获取当前用户名,同样来自UserNameToken return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name; }
简单来说,WCF会自动解析SOAP请求头里的UserNameToken节点,把Username字段的值传递到Validate方法的参数中,你完全不用自己去解析XML,直接用框架提供的API就搞定了!
内容的提问来源于stack exchange,提问作者user1713059
相关产品推荐
相关产品推荐

