You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:27:37