首先在服务中加入如下方法用于校验,Header的信息:如果 Header 中 Authorization 的字符串不是"fangxing/123" 那么就将返回 405 MethodNotAllowed 的错误。这个字符串的内容可以自定义,反正服务端根据某种规则检查这个字符串。
private bool CheckAuthorization() { var ctx = WebOperationContext.Current; var auth = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization]; if (string.IsNullOrEmpty(auth) || auth != "fangxing/123") { ctx.OutgoingResponse.StatusCode = HttpStatusCode.MethodNotAllowed; return false; } 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 对象。
这样就不用每次调用都去加验证信息了。
var url = "http://localhost:3433/TaskService/All"; var client = new HttpClient(); client.DefaultHeaders.Add("Authorization", "fangxing/123"); var resp = client.Get(url);
public class SecureWebServiceHostFactory : WebServiceHostFactory { protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { var host = base.CreateServiceHost(serviceType, baseAddresses); host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager(); return host; } public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses) { var host = base.CreateServiceHost(constructorString, baseAddresses); host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager(); return host; } } public class MyServiceAuthorizationManager : ServiceAuthorizationManager { protected override bool CheckAccessCore(OperationContext operationContext) { var ctx = WebOperationContext.Current; var auth = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization]; if (string.IsNullOrEmpty(auth) || auth != "fangxing/123") { ctx.OutgoingResponse.StatusCode = HttpStatusCode.MethodNotAllowed; return false; } return true; } }
var securewebServiceHostFactory = new SecureWebServiceHostFactory(); RouteTable.Routes.Add(new ServiceRoute("TaskService", securewebServiceHostFactory, typeof(TaskService)));
这样服务端代码就可以去掉 CheckAuthorization() 而把验证工作都交给 SecureWebServiceHostFactory 了。
这种验证方式,其实也是现在 Windows Auzer Access Control 的原型。 只不过这个 Authoriztion 的服务是专门的Services罢了。
1. 客户端先从发布令牌的服务获取令牌; 2. 客户端拿着令牌提交到现在的服务; 3.服务端将客户端令牌拿到发布令牌的服务上校验。
源码下载:http://download.csdn.net/download/fangxinggood/3686322