WCF4.0 –- RESTful WCF Services (4) (Basic Security)

本文介绍在RESTWCF服务中如何实现简单的用户名验证,包括客户端如何添加验证信息及服务端如何统一拦截验证,同时提供了统一的授权管理工厂类以简化服务端验证逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在REST架构的WCF服务中,它不像一般的WCF服务绑定,有配套的安全模式,实现起来那么简单。REST WCF服务只能在传输层加密,而一般的WCF 服务可以在消息层加密。因此 REST WCF服务启用ASP.NET兼容模式后,它的安全是由ASP.NET来保证的。本篇文章主要介绍在 REST WCF 中如何实现最简单的 Username 验证。

在SOAP协议的WCF中,可以通过SOAPHeader(MessageHeader)来实现用户名密码的传输,早在WebService时代我们就这么用过了。在REST WCF中,我们可以利用 HttpHeader 来完成这一目标。 (你可不会想在每个服务契约里加上用户和密码的参数吧...)

首先在服务中加入如下方法用于校验,Header的信息:如果 Header 中 Authorization 的字符串不是"fangxing/123" 那么就将返回 405 MethodNotAllowed 的错误。这个字符串的内容可以自定义,反正服务端根据某种规则检查这个字符串。

[c-sharp] view plain copy print ?
  1. private bool CheckAuthorization() 
  2.     var ctx = WebOperationContext.Current; 
  3.     var auth = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization]; 
  4.     if (string.IsNullOrEmpty(auth) || auth != "fangxing/123"
  5.     { 
  6.         ctx.OutgoingResponse.StatusCode = HttpStatusCode.MethodNotAllowed; 
  7.         return false
  8.     } 
  9.     return true

然后在每一个服务契约的实现中,都去调用它。
[WebGet(UriTemplate = "All")]
public List<Task> GetTask()
{
    if (!CheckAuthorization())
        return null;
    return GetData();
}

[WebGet(UriTemplate = "{taskId}")]
public Task GetTaskById(string taskId)
{
    if (!CheckAuthorization())
        return null;
    return GetData().FirstOrDefault(t => t.Id==taskId);
}

现在的服务,如果直接通过浏览器访问,将得到 405 MethodNotAllowed 的错误:


客户端只要相应的验证信加到 RequestHeader 中去,就可以访问了。客户端可以使用单例模式设计 Client 对象。
这样就不用每次调用都去加验证信息了。

[c-sharp] view plain copy print ?
  1. var url = "http://localhost:3433/TaskService/All"
  2. var client = new HttpClient(); 
  3. client.DefaultHeaders.Add("Authorization", "fangxing/123"); 
  4. var resp = client.Get(url); 

* 这里使用的是 Microsoft.Http.HttpClient (WCF REST Starter Kit) 而非 System.Net.WebClient

回头看服务端代码,每个服务实现中都需要加上 CheckAuthorization() 是不是很烦?
OK,我们知道这个 REST WCF服务是承载在一个Web Application上的, 通过往 RouteTable 中注册 WebServiceHostFactory 来激活服务对象的。 那么只要对这个 WebServiceHostFactory 做些“手脚”,就可以实现服务端验证的统一拦截,代码如下。(一般的 WCF 也可以利用此方法对 MessageHeader 进行拦截校验)

[c-sharp] view plain copy print ?
  1. public class SecureWebServiceHostFactory : WebServiceHostFactory 
  2.     protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
  3.     { 
  4.         var host = base.CreateServiceHost(serviceType, baseAddresses); 
  5.         host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager(); 
  6.         return host; 
  7.     } 
  8.  
  9.     public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses) 
  10.     { 
  11.         var host = base.CreateServiceHost(constructorString, baseAddresses); 
  12.         host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager(); 
  13.         return host; 
  14.     } 
  15.  
  16. public class MyServiceAuthorizationManager : ServiceAuthorizationManager 
  17.     protected override bool CheckAccessCore(OperationContext operationContext) 
  18.     { 
  19.         var ctx = WebOperationContext.Current; 
  20.         var auth = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization]; 
  21.         if (string.IsNullOrEmpty(auth) || auth != "fangxing/123"
  22.         { 
  23.             ctx.OutgoingResponse.StatusCode = HttpStatusCode.MethodNotAllowed; 
  24.             return false
  25.         } 
  26.         return true
  27.     } 


RegisterRoutes 里的工厂类也需要相应的修改下:
[c-sharp] view plain copy print ?
  1. var securewebServiceHostFactory = new SecureWebServiceHostFactory(); 
  2. RouteTable.Routes.Add(new ServiceRoute("TaskService"
  3.     securewebServiceHostFactory, typeof(TaskService))); 


这样服务端代码就可以去掉 CheckAuthorization() 而把验证工作都交给 SecureWebServiceHostFactory 了。

这种验证方式,其实也是现在 Windows Auzer Access Control 的原型。 只不过这个 Authoriztion 的服务是专门的Services罢了。
1. 客户端先从发布令牌的服务获取令牌; 2. 客户端拿着令牌提交到现在的服务; 3.服务端将客户端令牌拿到发布令牌的服务上校验。


源码下载:http://download.youkuaiyun.com/download/fangxinggood/3686322


【REST WCF系列】
RESTful WCF Services (1) (入门)
RESTful WCF Services (2) (实现增,删,改,查)
RESTful WCF Services (3) (Raw Stream)
RESTful WCF Services (4) (Basic Security)
RESTful WCF Services (实例) (并发同步服务 SyncService)

<think>好的,用户让我用C#写两个接口,分别用WebService和WebAPI,还要做区别分析。首先,我需要确认用户的需求。可能他们正在学习C#的不同Web技术,或者在工作中需要集成这两种服务,想了解它们的区别和实现方式。 首先,我得回忆一下WebService和WebAPI的区别。WebService通常指ASMX类型的,基于SOAP,使用WSDL描述,一般返回XML。而WebAPI属于ASP.NET Core或MVC的一部分,基于REST,支持JSON等多种格式,更灵活轻量。用户可能需要对比这两种技术的实现步骤和特点。 接下来,考虑如何用C#实现这两个接口。对于WebService,可能需要创建一个ASP.NET Web Application(.NET Framework),添加ASMX文件。而WebAPI的话,如果是用较新的.NET Core,就需要创建API控制器,配置路由等。 然后,我需要分别写出两个示例代码。WebService的例子可能包括一个简单的加法方法,用WebMethod特性。WebAPI的例子则用Controller基类,HttpGet特性,返回JSON结果。要注意代码的正确性和可运行性。 区别分析部分,要涵盖协议、数据格式、通信方式、应用场景等方面。比如,WebService适合企业内部集成,支持事务和安全性高的场景;而WebAPI适合移动应用或前后端分离,需要灵活数据格式的情况。 同时,用户可能想了解两者的优缺点,比如WebService的强类型和标准化,但配置复杂;WebAPI的轻量和易用性,适合现代开发。可能还需要提到RESTful原则和SOAP的区别,比如状态和动词的使用。 还要考虑用户是否有.NET Framework和.NET Core的环境差异,是否需要说明版本兼容性?比如WebService在.NET Core中不被推荐,通常使用WCF代替,但用户可能还在维护旧项目,所以示例用传统的ASMX。 最后,总结使用场景,帮助用户根据需求选择合适的技术。确保解释清晰,让用户明白两者的适用场合和如何选择。</think>以下是用 C# 实现 WebService 和 WebAPI 的示例代码及对比分析: --- ### 一、WebService 示例 (ASMX) ```csharp // CalculatorService.asmx using System.Web.Services; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class CalculatorService : WebService { [WebMethod] public int Add(int a, int b) { return a + b; } } ``` --- ### 二、WebAPI 示例 (ASP.NET Core) ```csharp // Controllers/CalculatorController.cs using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/[controller]")] public class CalculatorController : ControllerBase { [HttpGet("add")] public IActionResult Add(int a, int b) { return Ok(a + b); } } ``` --- ### 三、核心区别分析 | **特性** | **WebService (ASMX)** | **WebAPI** | |--------------------|-----------------------------------------------|----------------------------------------| | **协议标准** | SOAP 协议 | HTTP 协议 (RESTful 风格) | | **数据格式** | 仅支持 XML | 支持 JSON/XML/Protobuf 等 | | **通信方式** | 基于 WSDL 的严格规范 | 基于 HTTP 动词 (GET/POST/PUT/DELETE) | | **宿主环境** | 仅限 IIS | 跨平台 (IIS/Kestrel/Docker 等) | | **序列化** | XML 序列化 (XmlSerializer) | JSON 序列化 (默认) | | **开发效率** | 配置复杂,需手动添加 WebMethod | 基于特性路由,开发便捷 | | **应用场景** | 企业级系统集成 (如银行系统) | 现代应用/移动端接口/前后端分离 | | **扩展性** | 通过 WS-* 协议扩展 | 通过中间件和过滤器扩展 | | **性能** | XML 解析开销较大 | JSON 轻量,性能更优 | | **客户端调用** | 需生成代理类 (WSDL) | 直接 HTTP 请求调用 | --- ### 四、选择建议 1. **选 WebService** 当需要: - 与企业级 SOAP 系统集成 - 需要 WS-Security 等高级协议 - 强类型契约优先的场景 2. **选 WebAPI** 当需要: - 构建 RESTful 风格 API - 支持移动端/前端框架调用 - 追求高性能和开发效率 - 需要灵活的数据格式交换 --- ### 五、发展趋势 WebAPI 已成为现代 .NET 开发的主流选择,而 WebService 更多用于维护遗留系统。对于新项目,推荐使用 ASP.NET Core WebAPI + OpenAPI (Swagger) 组合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值