首页 > 其他分享 >在surging 微服务引擎下如何搭建webservice和身份验证

在surging 微服务引擎下如何搭建webservice和身份验证

时间:2023-03-19 23:12:08浏览次数:43  
标签:OperationContext webservice System 身份验证 surging new var using public

一、前言

       现实生产中,有一些比较老的系统对外提供的接口都是WebService,尤其是比较老的系统都是围绕ESB进行搭建,而对外提供就需要WebService ,为了更好完善其解决方案,故集成了webservice 协议组件和身份验证,现把它上传至github, 而这篇文章就是讲述如何构建WebService,创建的接口IWebServiceService代码如下:

using Surging.Core.CPlatform.Ioc;
using Surging.Core.CPlatform.Runtime.Server.Implementation.ServiceDiscovery.Attributes;
using Surging.IModuleServices.Common.Models;
using System.ServiceModel;
using System.Threading.Tasks;

namespace Surging.IModuleServices.Common
{
    [ServiceBundle("api/{Service}/{Method}")]
    [ServiceContract]
    public  interface IWebServiceService : IServiceKey
    {
        [OperationContract]
        Task<string> SayHello(string name);

        [OperationContract]
        Task<string> Authentication(AuthenticationRequestData requestData);
    }
}
AuthenticationRequestData 代码如下:
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;

namespace Surging.IModuleServices.Common.Models
{
    [ProtoContract]
    [DataContract]
    public class AuthenticationRequestData
    {
        [ProtoMember(1)]
        [DataMember]
        public string UserName { get; set; }

        [ProtoMember(2)]
        [DataMember]
        public string Password { get; set; }
    }
}
从以上代码来看,除了需要符合引擎代码规则外,还需要添加[ServiceContract]和[OperationContract] 特性, 如果参数是实体的话,需要添加在实体模型上加[DataContract]和 属性上加[DataMember]

那么创建的业务服务WebServiceService代码如下:

using Surging.Core.ApiGateWay.OAuth;
using Surging.Core.Protocol.WebService.Runtime;
using Surging.IModuleServices.Common;
using Surging.IModuleServices.Common.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Surging.Modules.Common.Domain
{
    public class WebServiceService : WebServiceBehavior, IWebServiceService
    {
        private readonly IAuthorizationServerProvider _authorizationServerProvider;
        public WebServiceService(IAuthorizationServerProvider authorizationServerProvider)
        {
            _authorizationServerProvider = authorizationServerProvider;
        }
        public async Task<string> SayHello(string name)
        {
            var token = this.HeaderValue.Token;
            if (await _authorizationServerProvider.ValidateClientAuthentication(token))
                return $"Hello,{name}";
            else
                return " Please leave, stranger";
        }

         public   async Task<string> Authentication(AuthenticationRequestData requestData)
        {
            var param = new Dictionary<string, object>();
            param.Add("requestData", requestData);
            var result=  await _authorizationServerProvider.GenerateTokenCredential(param);
            return result;
        }
    }
}

通过以上代码,首先需要继承IWebServiceService和WebServiceBehavior,然后通过IAuthorizationServerProvider 去生成Token 和验证Token,  或者也可以脱离引擎的身份鉴权,通过传递的this.HeaderValue.Token 进行验证。

通过访问127.0.0.1:289/api/webservice/sayhello.asmx,显示以下界面,说明基于webservice 的服务就已经添加成功。

 

 

 

二、引用WebService

首先我们在创建好的控制台项目里面添加WebService的引用。

 

 

1、在依赖项上面右键,选择“添加服务引用”,选择wcf web service如图所示:

 

 添加服务引用。如图所示:

 配置完以后,点击“下一步”,去掉重新使用引用的程序集中的类型签名的复选框。

 

  直接点击“完成”按钮即可。慢慢等待配置完成:

 

 配置完成界面如图所示:

 

 

 

 下面就介绍如何在.net 6.0下调用webservice

三、调用WebService

在Program类文件中,调用webservice 提供的sayhello,在调用前需要生成token, 通过token才能正确访问结果,以下是基于.net 6.0,代码如下:

 

 1 // See https://aka.ms/new-console-template for more information
 2 using ConsoleApp7;
 3 using ServiceReference1;
 4 using System.ServiceModel;
 5 
 6 try
 7 {
 8 
 9 
10     WebServiceServiceClient client = new WebServiceServiceClient(); 
11     using (var scope = new FlowingOperationContextScope(client.InnerChannel))
12     {
13         var authenticationResponse = await client.AuthenticationAsync(new AuthenticationRequestData
14         {
15             UserName = "admin",
16             Password = "admin"
17         }).ContinueOnScope(scope);
18         var authenticationResult = authenticationResponse.Body.AuthenticationResult;
19         if (authenticationResponse.Body.AuthenticationResult != null)
20         {
21             var header1 = System.ServiceModel.Channels.MessageHeader.CreateHeader("headerValue", "http://tempuri.org/", new HeaderValue
22             {
23                 Token = authenticationResult
24             });
25             OperationContext.Current.OutgoingMessageHeaders.Add(header1);
26             var sayHelloResponse =await client.SayHelloAsync("fanly").ContinueOnScope(scope);
27             Console.WriteLine(sayHelloResponse.Body.SayHelloResult);
28             Console.ReadLine();
29         }
30 
31     }
32 
33 }
34 catch (Exception ex)
35 {
36     Console.WriteLine(ex.Message);
37 }

以下是基于.net framework 调用webservice 的代码:

 1     internal class Program
 2     {
 3         static  async Task Main(string[] args)
 4         {
 5             try
 6             {
 7 
 8                 WebServiceServiceClient client = new WebServiceServiceClient();
 9                 using (var scope = new OperationContextScope(client.InnerChannel))
10                 {
11                     var authenticationResponse = client.Authentication(new AuthenticationRequestData
12                     {
13                         UserName = "admin",
14                         Password = "admin"
15                     });
16                     if (authenticationResponse != null)
17                     {
18                         var header1 = System.ServiceModel.Channels.MessageHeader.CreateHeader("headerValue", "http://tempuri.org/", new HeaderValue
19                         {
20                             Token = authenticationResponse
21                         });
22                         OperationContext.Current.OutgoingMessageHeaders.Add(header1);
23                         var sayHelloResponse = client.SayHello("fanly");
24                         Console.WriteLine(sayHelloResponse);
25                         Console.ReadLine();
26                     }
27 
28                 }
29                
30             }
31             catch (Exception ex)
32             {
33                 Console.WriteLine(ex.Message);
34             }
35         }
36     }

 

 

HeaderValue 代码如下:

namespace ConsoleApp7
{
    public class HeaderValue
    {
        public string Token { get; set; }
    }
}

因为.net 6.0 生成的代码是异步,所以就要修改OperationContextScope 以支持异步,代码如下:

  1  public sealed class FlowingOperationContextScope : IDisposable
  2     {
  3         bool _inflight = false;
  4         bool _disposed;
  5         OperationContext _thisContext = null;
  6         OperationContext _originalContext = null;
  7 
  8         public FlowingOperationContextScope(IContextChannel channel):
  9             this(new OperationContext(channel))
 10         {
 11         }
 12 
 13         public FlowingOperationContextScope(OperationContext context)
 14         {
 15             _originalContext = OperationContext.Current;
 16             OperationContext.Current = _thisContext = context;
 17         }
 18 
 19         public void Dispose()
 20         {
 21             if (!_disposed)
 22             {
 23                 if (_inflight || OperationContext.Current != _thisContext)
 24                     throw new InvalidOperationException();
 25                 _disposed = true;
 26                 OperationContext.Current = _originalContext;
 27                 _thisContext = null;
 28                 _originalContext = null;
 29             }
 30         }
 31 
 32         internal void BeforeAwait()
 33         {
 34             if (_inflight)
 35                 return;
 36             _inflight = true; 
 37         }
 38 
 39         internal void AfterAwait()
 40         {
 41             if (!_inflight)
 42                 throw new InvalidOperationException();
 43             _inflight = false; 
 44             OperationContext.Current = _thisContext;
 45         }
 46     }
 47      
 48     public static class TaskExt
 49     {
 50         public static SimpleAwaiter<TResult> ContinueOnScope<TResult>(this Task<TResult> @this, FlowingOperationContextScope scope)
 51         {
 52             return new SimpleAwaiter<TResult>(@this, scope.BeforeAwait, scope.AfterAwait);
 53         }
 54          
 55         public class SimpleAwaiter<TResult> :
 56             System.Runtime.CompilerServices.INotifyCompletion
 57         {
 58             readonly Task<TResult> _task;
 59 
 60             readonly Action _beforeAwait;
 61             readonly Action _afterAwait;
 62 
 63             public SimpleAwaiter(Task<TResult> task, Action beforeAwait, Action afterAwait)
 64             {
 65                 _task = task;
 66                 _beforeAwait = beforeAwait;
 67                 _afterAwait = afterAwait;
 68             }
 69 
 70             public SimpleAwaiter<TResult> GetAwaiter()
 71             {
 72                 return this;
 73             }
 74 
 75             public bool IsCompleted
 76             {
 77                 get
 78                 { 
 79                     if (_task.IsCompleted)
 80                         return true;
 81                     _beforeAwait();
 82                     return false;
 83                 }
 84 
 85             }
 86 
 87             public TResult GetResult()
 88             {
 89                 return _task.Result;
 90             }
 91 
 92             // INotifyCompletion
 93             public void OnCompleted(Action continuation)
 94             {
 95                 _task.ContinueWith(task =>
 96                 {
 97                     _afterAwait();
 98                     continuation();
 99                 },
100                 CancellationToken.None,
101                 TaskContinuationOptions.ExecuteSynchronously,
102                 SynchronizationContext.Current != null ?
103                     TaskScheduler.FromCurrentSynchronizationContext() :
104                     TaskScheduler.Current);
105             }
106         }
107     }

程序输出结果:

 

 

四、结尾

        surging 正在开发微服务平台(以处于调试阶段),形成独立的项目产品,抛弃之前的代码架构的形式,现如今已经攘括支持WEB, 物联网,流媒体等多种业务场景, 现在开发支持了外层协议有:MQTT,Grpc,, DNS,  TCP,UDP,restful,rtmp,httpflv,rtsp,websocket,webservice, 内部可以通过基于thrift 或者netty 做到可靠性的RPC调用,因为有服务治理,服务发现,并且支持了Apollo配置中心,skywalking 链路跟踪,并且支持JAVA和.NET主流开发语言,请大家多多留意surging 的微服务平台。或者你也可以加群联系到我:744677125(老群被封,这是新群)

 

 

 

标签:OperationContext,webservice,System,身份验证,surging,new,var,using,public
From: https://www.cnblogs.com/fanliang11/p/17226191.html

相关文章