.NET 6下WCFCore集成ServiceAuthorizationManager失效求助
问题根源
你遇到的核心问题是代码配置与配置文件的冲突:在Program.cs中你通过AddServiceEndpoint手动创建了服务端点,这属于代码优先的配置方式,会覆盖wcf.config中的服务配置,导致你在<serviceAuthorization>中指定的OAuthAuthorizationManager没有被关联到实际运行的服务上。
解决方案
提供两种可行的解决方式,根据你的需求选择:
方式一:完全依赖配置文件加载服务
修改Program.cs,移除手动添加端点的代码,让CoreWCF自动读取wcf.config中的服务配置:
var builder = WebApplication.CreateBuilder(); builder.Services.AddServiceModelServices(); builder.Services.AddServiceModelConfigurationManagerFile("wcf.config"); builder.Services.AddServiceModelMetadata(); builder.Services.AddSingleton<IServiceBehavior, UseRequestHeadersForMetadataAddressBehavior>(); builder.Services.AddSingleton<OAuthAuthorizationManager>(); var app = builder.Build(); // 仅调用UseServiceModel,不手动添加端点,让配置文件生效 app.UseServiceModel(); // 配置元数据HTTPS获取 var mb = app.Services.GetRequiredService<ServiceMetadataBehavior>(); mb.HttpsGetEnabled = true; app.Run();
这样wcf.config中的<service>和<behavior>配置会被正确加载,OAuthAuthorizationManager会被应用到服务上。
方式二:代码中手动配置授权行为
如果需要保留代码添加端点的方式,直接在代码中配置ServiceAuthorizationBehavior,无需依赖配置文件:
首先确保你的OAuthAuthorizationManager实现正确重写CheckAccessCore方法:
public class OAuthAuthorizationManager : ServiceAuthorizationManager { protected override bool CheckAccessCore(OperationContext operationContext) { // 从HTTP请求头获取Bearer令牌 if (!operationContext.RequestContext.RequestMessage.Properties.TryGetValue(HttpRequestMessageProperty.Name, out var propObj)) { return false; } var httpProp = (HttpRequestMessageProperty)propObj; var authHeader = httpProp.Headers[HttpRequestHeader.Authorization]; if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { return false; } var token = authHeader.Substring("Bearer ".Length).Trim(); // 替换为你的实际令牌验证逻辑(比如JWT解析、调用OAuth验证接口) return ValidateToken(token); } private bool ValidateToken(string token) { // 示例:简单验证,实际替换为真实业务逻辑 return !string.IsNullOrEmpty(token) && token.Length > 10; } }
然后修改Program.cs中的UseServiceModel代码,添加授权行为:
app.UseServiceModel(bld => { var serviceEndpoint = bld.AddServiceEndpoint<Service, IService>( new BasicHttpBinding(BasicHttpSecurityMode.Transport), "/Service.svc" ); // 获取服务的行为集合,添加授权行为 var serviceHost = bld.Services.GetRequiredService<ServiceHostBase>(); var authBehavior = serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>() ?? new ServiceAuthorizationBehavior(); authBehavior.ServiceAuthorizationManager = new OAuthAuthorizationManager(); if (!serviceHost.Description.Behaviors.Contains(authBehavior)) { serviceHost.Description.Behaviors.Add(authBehavior); } var mb = app.Services.GetRequiredService<ServiceMetadataBehavior>(); mb.HttpsGetEnabled = true; });
验证步骤
- 启动服务后,用客户端工具(比如Postman、SOAP UI)调用服务,不携带Bearer令牌,应该返回访问拒绝的错误。
- 携带有效的Bearer令牌调用,服务应正常执行操作。
内容的提问来源于stack exchange,提问作者user729400
相关产品推荐
相关产品推荐

