升级至.NET Core后,如何通过Microsoft WCF Web服务引用提供程序获取WCF凭据?
解决.NET Core访问WCF服务的凭据传递与授权问题
我来帮你搞定这个迁移中遇到的WCF凭据问题——毕竟从.NET Framework的WCF转到.NET Core,这类安全配置的适配确实容易踩坑。
一、修复TransportCredentialOnly端点的凭据传递与PrincipalPermission授权问题
首先要明确:TransportCredentialOnly模式下,凭据是通过HTTP层传递的(默认是Basic认证),而不是消息加密层,这和你原来的TransportWithMessageCredential模式完全不同,所以原来的凭据传递逻辑需要调整:
1. 服务端配置调整
确保你的WCF服务端的TransportCredentialOnly端点配置正确:
- 在绑定配置里,设置安全模式为
TransportCredentialOnly,并指定客户端凭据类型为Basic:<bindings> <basicHttpBinding> <binding name="TransportCredentialOnlyBinding"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Basic" /> </security> </binding> </basicHttpBinding> </bindings> - 配置服务行为,指定用户名密码的验证方式(比如自定义验证器、Windows认证或MembershipProvider):
如果用自定义验证器,要确保验证通过后正确设置用户身份,比如在验证器的<behaviors> <serviceBehaviors> <behavior name="ServiceBehavior"> <serviceCredentials> <!-- 这里用自定义验证器举例,你可以换成自己的验证逻辑 --> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="YourNamespace.CustomPasswordValidator, YourAssembly" /> </serviceCredentials> <!-- 开启PrincipalPermission支持,指定身份验证模式 --> <serviceAuthorization principalPermissionMode="UseAspNetRoles" /> </behavior> </serviceBehaviors> </behaviors>Validate方法里:public override void Validate(string userName, string password) { // 你的验证逻辑 if (!IsValidUser(userName, password)) throw new FaultException("Invalid credentials"); // 设置当前身份,让PrincipalPermission能识别 ServiceSecurityContext.Current.PrimaryIdentity = new GenericIdentity(userName); }
2. .NET Core客户端配置调整
通过WCF Web服务引用生成的客户端,默认可能不会自动适配TransportCredentialOnly的绑定,所以需要手动调整绑定并设置凭据:
// 手动创建符合要求的绑定 var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly); binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; // 创建客户端实例 var client = new YourWcfServiceClient(binding, new EndpointAddress("http://your-service-endpoint-url")); // 设置用户名密码(这里会自动转为HTTP Basic Auth的请求头) client.ClientCredentials.UserName.UserName = "MyUserName"; client.ClientCredentials.UserName.Password = "MyPassword"; // 调用服务方法 try { var result = await client.YourProtectedMethodAsync(); } finally { await client.CloseAsync(); }
3. 验证PrincipalPermission生效
确保服务方法上的[PrincipalPermission]属性配置正确,比如:
[PrincipalPermission(SecurityAction.Demand, Name = "MyUserName")] public string YourProtectedMethod() { // 方法逻辑 return "Authorized content"; }
如果服务端配置正确,客户端传递的凭据会被验证,并且PrincipalPermission会检查当前用户身份是否匹配。
二、通过WCF Web服务引用提供程序获取服务凭据
1. 获取客户端已设置的凭据
生成的客户端类自带ClientCredentials属性,你可以直接通过它访问或修改凭据:
var client = new YourWcfServiceClient(); // 获取已设置的用户名 var currentUserName = client.ClientCredentials.UserName.UserName; // 修改密码 client.ClientCredentials.UserName.Password = "NewPassword";
2. 获取服务端的凭据信息(如证书)
如果你的服务端使用了证书身份验证,你可以通过客户端的端点行为获取服务端的证书信息:
var client = new YourWcfServiceClient(); // 从端点行为中找到ClientCredentials var serviceCredentials = client.Endpoint.Behaviors.Find<ClientCredentials>(); // 获取服务端的默认证书 var serviceCert = serviceCredentials.ServiceCertificate.DefaultCertificate;
3. 动态获取服务元数据中的凭据配置
如果需要从服务的WSDL元数据中读取安全配置,可以使用MetadataExchangeClient:
var mexClient = new MetadataExchangeClient(new Uri("http://your-service-url/mex"), MetadataExchangeClientMode.HttpGet); var metadataSet = mexClient.GetMetadata(); // 解析metadataSet中的安全配置节点,获取凭据相关信息
不过一般来说,生成客户端时已经根据元数据自动配置了绑定,大部分场景下直接调整ClientCredentials即可。
常见排查点
- 抓包验证:用Fiddler或浏览器开发者工具检查请求头是否包含
Authorization: Basic xxx,确认凭据是否正确发送。 - IIS配置:如果服务托管在IIS,要确保站点启用了Basic认证,并且禁用了匿名认证(如果需要强制验证)。
- 权限问题:确保服务端的验证器有权限访问用户存储(比如数据库、AD),避免验证过程中抛出未捕获的异常。
内容的提问来源于stack exchange,提问作者John Arundell
相关产品推荐
相关产品推荐

