李思淳 5 yıl önce
ebeveyn
işleme
bccacee321

+ 1 - 1
TEAMModelGrpc/Protos/KnowledgeService.proto

@@ -1,5 +1,5 @@
 syntax = "proto3";
-option csharp_namespace = "TEAMModelGrpc";
+option csharp_namespace = "TMDGrpc";
 package math;
 
 

+ 72 - 4
TEAMModelGrpc/Startup.cs

@@ -1,15 +1,26 @@
 using System;
 using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
 using System.Linq;
+using System.Security.Claims;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Grpc.Extension.AspNetCore;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Primitives;
+using Microsoft.IdentityModel.Tokens;
 using TEAMModelGrpc.Services;
+using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
+using TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration;
+using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.Module.AzureTable.Implements;
+using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
 
 namespace TEAMModelGrpc
 {
@@ -27,36 +38,93 @@ namespace TEAMModelGrpc
             services.AddGrpc();
             //添加Grpc扩展
             services.AddGrpcExtensions(_conf);
+
+            services.AddAuthorization(options =>
+            {
+                options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
+                {
+                    policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
+                    policy.RequireClaim(ClaimTypes.Name);
+                });
+            });
+            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+                .AddJwtBearer(options =>
+                {
+                    options.TokenValidationParameters =
+                        new TokenValidationParameters
+                        {
+                            ValidateAudience = false,
+                            ValidateIssuer = false,
+                            ValidateActor = false,
+                            ValidateLifetime = true,
+                            IssuerSigningKey = SecurityKey
+                        };
+                });
+
+            // Table配置
+            services.AddScoped<IAzureTableDBRepository, AzureTableDBRepository>();
+            //使用Blob配置
+            services.AddAzureBlobStorage().AddConnection(_conf.GetSection("Azure:Blob").Get<AzureBlobOptions>());
+            //使用CosmosDB
+            services.AddAzureCosmosDBV3().AddCosmosDBV3Connection(_conf.GetSection("Azure:CosmosDB").Get<AzureCosmosDBOptions>())
+                .AddCosmosSerializer(new SystemTextJsonCosmosSerializer(new JsonSerializerOptions() { IgnoreNullValues = true }));
+
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
-        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAzureCosmosDBV3Repository cosmosDBV3Repository)
         {
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
             }
-
+            cosmosDBV3Repository.InitializeDatabase();
             app.UseRouting();
 
+            //注册 ASP.NET Core 身份验证中间件的顺序很重要。 
+            //始终在 UseRouting 之后和 UseEndpoints 之前调用 UseAuthentication 和 UseAuthorization。
+            app.UseAuthentication();
+            app.UseAuthorization();
+
             app.UseEndpoints(endpoints =>
             {
                 endpoints.MapGrpcService<GreeterService>();
 
+                endpoints.MapGet("/generateJwtToken", context =>
+                {
+                    return context.Response.WriteAsync(GenerateJwtToken(context.Request.Query["name"]));
+                });
+
                 endpoints.MapGet("/", async context =>
                 {
                     await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
                 });
             });
             //CodeFirst的Grpc(会自动扫描TStartup所在程序集下的IGrpcSerivce)
-            app.UseGrpcExtensions<KnowledgeService>(options =>
+            app.UseGrpcExtensions<TEAMModelGrpc.Services.KnowledgeService>(options =>
             {
                 //CodeFirst配制
                 options.GlobalPackage = "math";
-                options.ProtoNameSpace = "TEAMModelGrpc";
+                options.ProtoNameSpace = "TMDGrpc";
             })
             //CodeFirst生成proto
             .UseProtoGenerate("protos", false);
         }
+
+        private string GenerateJwtToken(string name)
+        {
+            if (string.IsNullOrEmpty(name))
+            {
+                throw new InvalidOperationException("Name is not specified.");
+            }
+
+            var claims = new[] { new Claim(ClaimTypes.Name, name) };
+            var credentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256);
+            var token = new JwtSecurityToken("ExampleServer", "ExampleClients", claims, expires: DateTime.Now.AddSeconds(60), signingCredentials: credentials);
+            return JwtTokenHandler.WriteToken(token);
+        }
+
+        private readonly JwtSecurityTokenHandler JwtTokenHandler = new JwtSecurityTokenHandler();
+        private readonly SymmetricSecurityKey SecurityKey = new SymmetricSecurityKey(Guid.NewGuid().ToByteArray());
     }
 }

+ 5 - 0
TEAMModelGrpc/TEAMModelGrpc.csproj

@@ -8,6 +8,10 @@
     <DocumentationFile>TEAMModelOS.GRPC.xml</DocumentationFile>
   </PropertyGroup>
 
+  <ItemGroup>
+    <None Remove="Protos\KnowledgeService.proto" />
+  </ItemGroup>
+
   <ItemGroup>
     <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
     <PackageReference Include="Grpc.Tools" Version="2.27.0">
@@ -23,6 +27,7 @@
 
   <ItemGroup>
     <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
+    <Protobuf Include="Protos\KnowledgeService.proto" GrpcServices="Server" />
   </ItemGroup>
 
 </Project>

+ 66 - 0
TEAMModelGrpc/TEAMModelOS.GRPC.xml

@@ -80,5 +80,71 @@
             <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
             <param name="serviceImpl">An object implementing the server-side handling logic.</param>
         </member>
+        <member name="T:TMDGrpc.KnowledgeServiceReflection">
+            <summary>Holder for reflection information generated from Protos/KnowledgeService.proto</summary>
+        </member>
+        <member name="P:TMDGrpc.KnowledgeServiceReflection.Descriptor">
+            <summary>File descriptor for Protos/KnowledgeService.proto</summary>
+        </member>
+        <member name="F:TMDGrpc.RequestDict.DictFieldNumber">
+            <summary>Field number for the "dict" field.</summary>
+        </member>
+        <member name="P:TMDGrpc.RequestDict.Dict">
+             <summary>
+            查询dict
+             </summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.IdFieldNumber">
+            <summary>Field number for the "id" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.TypeFieldNumber">
+            <summary>Field number for the "type" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.NameFieldNumber">
+            <summary>Field number for the "name" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.AliasFieldNumber">
+            <summary>Field number for the "alias" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.SubjectCodeFieldNumber">
+            <summary>Field number for the "subjectCode" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.ScopeCodeFieldNumber">
+            <summary>Field number for the "scopeCode" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.OrderFieldNumber">
+            <summary>Field number for the "order" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.StatusFieldNumber">
+            <summary>Field number for the "status" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.PointsFieldNumber">
+            <summary>Field number for the "points" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.KnowledgeIdFieldNumber">
+            <summary>Field number for the "knowledgeId" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.SourceFieldNumber">
+            <summary>Field number for the "source" field.</summary>
+        </member>
+        <member name="F:TMDGrpc.Knowledge.PeriodFieldNumber">
+            <summary>Field number for the "period" field.</summary>
+        </member>
+        <member name="P:TMDGrpc.KnowledgeService.Descriptor">
+            <summary>Service descriptor</summary>
+        </member>
+        <member name="T:TMDGrpc.KnowledgeService.KnowledgeServiceBase">
+            <summary>Base class for server-side implementations of KnowledgeService</summary>
+        </member>
+        <member name="M:TMDGrpc.KnowledgeService.BindService(TMDGrpc.KnowledgeService.KnowledgeServiceBase)">
+            <summary>Creates service definition that can be registered with a server</summary>
+            <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+        </member>
+        <member name="M:TMDGrpc.KnowledgeService.BindService(Grpc.Core.ServiceBinderBase,TMDGrpc.KnowledgeService.KnowledgeServiceBase)">
+            <summary>Register service method with a service binder with or without implementation. Useful when customizing the  service binding logic.
+            Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+            <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+            <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+        </member>
     </members>
 </doc>

+ 52 - 0
TEAMModelGrpc/appsettings.json

@@ -11,5 +11,57 @@
     "EndpointDefaults": {
       "Protocols": "Http2"
     }
+  },
+  "urls": "https://*:5000",
+  "GrpcServer": {
+    //用于grpc启动后注册到服务发现的ip地址段
+    "ServiceAddress": "192.168.*.*:",
+    //是否启用服务注册和服务发现,默认是true
+    "EnableDiscovery": false,
+    //服务发现服务器地址
+    "DiscoveryUrl": "http://106.12.23.251:8500",
+    //注册到服务发现的服务名称
+    "DiscoveryServiceName": "TMDOSgRPC",
+    //服务发现主动TTL的时间(秒)
+    "DiscoveryTTLInterval": 10,
+    //注册到服务发现的服务Tag
+    "DiscoveryServiceTags": "v-1.0.0.1",
+    //默认错误码
+    "DefaultErrorCode": 4300000,
+    //Jaeger配制(OpenTracing)
+    "Jaeger": {
+      //是否启用Jaeger,默认false
+      "Enable": false,
+      "AgentIp": "192.168.8.11",
+      "AgentPort": 5775
+    }
+  },
+  "Azure": {
+    "Table": {
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelostest;AccountKey=QB/zYHHCAtZfl9tf4emL1Y9ZXGc6fqZ+nNbCxIHM70HnziC8dMdEAu7+Pa4mbKLlbswV90wWHAF3nMjrKB54Lw==;EndpointSuffix=core.chinacloudapi.cn"
+    },
+    "Blob": {
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn",
+      "Container": "teammodelos"
+    },
+    "CosmosDB": {
+      "ConnectionString": "https://192.168.8.128:8081",
+      "ConnectionKey": "ddwAeGSf8Lsf1kxPXmdqnyzzi3CkJ0KW2BTPZ7Zq1N7qbJic5j7AaQ+WbF86F3rnzuDgGM1yg8O7BUFo93iA8w==",
+      "Database": "TEAMModelOS",
+      "CollectionThroughput": 400,
+      "ScanModel": [ "TEAMModelOS.Service" ]
+    },
+    "Redis": {
+      "ConnectionString": "106.12.23.251:6379,password=habook,ssl=false,abortConnect=False,defaultDatabase=13,writeBuffer=10240,poolsize=50,prefix=habook:"
+    }
+  },
+  "HaBookAuth": {
+    "TeamModelRegistUrl": "https://account.habookaclass.biz/regist?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsb2dpbiIsImF1ZCI6ImNoZW5nZHVMb2dpbiIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYxMzUwNDcsIm5iZiI6MTUzNjEzNTA0NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.F4AnkbJrMRoZvJ6SC-lqZEYIYSoq5x8lvX6_a3YqSgM&callback=",
+    "TeamModelLoginUrl": "https://account.habookaclass.biz/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsb2dpbiIsImF1ZCI6ImNoZW5nZHVMb2dpbiIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYxMzUwNDcsIm5iZiI6MTUzNjEzNTA0NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.F4AnkbJrMRoZvJ6SC-lqZEYIYSoq5x8lvX6_a3YqSgM&callback=",
+    "AccountUrl": "https://api.habookaclass.biz/account",
+    "ServiceUrl": "https://api.habookaclass.biz/service",
+    "UserInfoKey": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJpZCIsImF1ZCI6ImNoZW5nZHVJZCIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYwNTIzNjcsIm5iZiI6MTUzNjA1MjM2NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.RGKDVtwFEp4OBctlHOuF6yqyI21fTz4cinCxjFCxkSQ",
+    "SchoolCodeKey": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzY2hvb2xDb2RlIiwiYXVkIjoiY2hlbmdkdVNjaG9vbENvZGUiLCJpc3MiOiJodHRwczovL2FwaS5oYWJvb2thY2xhc3MuYml6IiwiaWF0IjoxNTM2MDUyNDI3LCJuYmYiOjE1MzYwNTI0MjcsImV4cCI6MTU2NzU1NTIwMCwiaWRwIjoiSGFib29rIENvcmVTZXJ2aWNlIn0.8m5VH3Nz4N9EdMz8AexTOEuDVitcJZFKy9DfW_UQkSY",
+    "SmsKey": "Basic ZmYwMWM0YTJjODdmZmNkYTUyNjhmMDEwOmE0YTE5YTVjNTU2ZWVhZTNjZmZhNTI0Mg=="
   }
 }