Browse Source

更新接口

CrazyIter_Bin 4 years ago
parent
commit
7a2b576235

+ 30 - 5
TEAMModelOS.SDK/Extension/JwtAuthExtension.cs

@@ -42,15 +42,17 @@ namespace TEAMModelOS.SDK.Extension
 
             return serializeToken;
         }
-        public static string CreateAppToken(string issuer, string id,  string salt, string schoolID = "", int expire = 1)
+        public static string CreateApiToken(string issuer, string id,  string salt,string  name , string schoolID = "", int expire = 1)
         {
            
             // 設定要加入到 JWT Token 中的聲明資訊(Claims)  
             var payload = new JwtPayload {
-                { JwtRegisteredClaimNames.Iss, issuer }, //發行者
-                { JwtRegisteredClaimNames.Sub, id }, // APPID                  
+                { JwtRegisteredClaimNames.Iss, issuer }, //發行者 iss: jwt签发者
+                { JwtRegisteredClaimNames.Sub, id }, // APPID sub: jwt所面向的用户
+                { JwtRegisteredClaimNames.Aud, "" }, // aud: 接收jwt的一方
                 { JwtRegisteredClaimNames.Azp,schoolID}, // 學校簡碼,如果有的話
-                {"hash",Guid.NewGuid().ToString() }
+                {JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString() },
+                { "name",name}, // 用戶的顯示名稱
                 //{ JwtRegisteredClaimNames.Exp,DateTimeOffset.UtcNow.AddHours(expire).ToUnixTimeSeconds().ToString()},  // 到期的時間,必須為數字
                 //{ "name",name}, // 用戶的顯示名稱
                 //{ "picture",picture}, // 用戶頭像
@@ -72,7 +74,30 @@ namespace TEAMModelOS.SDK.Extension
 
             return serializeToken;
         }
-
+        public static bool ValidateApiToken(string token, string salt)
+        {
+            try
+            {
+                var handler = new JwtSecurityTokenHandler();
+                var validationParameters = new TokenValidationParameters
+                {
+                    RequireExpirationTime = true,
+                    ValidateIssuer = false,
+                    ValidateAudience = false,
+                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt)),
+                    //ValidateLifetime = false,
+                    //LifetimeValidator = LifetimeValidator,
+                    ClockSkew = TimeSpan.Zero
+                };
+                ClaimsPrincipal principal = handler.ValidateToken(token, validationParameters, out SecurityToken securityToken);
+                return true;
+            }
+            catch (Exception)
+            {
+                //Trace.WriteLine(ex.Message);
+                return false;
+            }
+        }
         public static bool ValidateAuthToken(string token, string salt)
         {
             try

+ 6 - 0
TEAMModelOS.sln

@@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelGrpc", "TEAMModelG
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelFunction", "TEAMModelFunction\TEAMModelFunction.csproj", "{78470113-6261-4F9A-9EF3-E315F060813D}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TEAMModelAPI", "TEAMModelAPI\TEAMModelAPI.csproj", "{2146FEEC-7178-4141-A8C7-CBEBAEE404A6}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -33,6 +35,10 @@ Global
 		{78470113-6261-4F9A-9EF3-E315F060813D}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{78470113-6261-4F9A-9EF3-E315F060813D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{78470113-6261-4F9A-9EF3-E315F060813D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2146FEEC-7178-4141-A8C7-CBEBAEE404A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2146FEEC-7178-4141-A8C7-CBEBAEE404A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2146FEEC-7178-4141-A8C7-CBEBAEE404A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2146FEEC-7178-4141-A8C7-CBEBAEE404A6}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 2 - 1
TEAMModelOS/Controllers/Core/OpenApiController.cs

@@ -70,7 +70,8 @@ namespace TEAMModelOS.Controllers.Core
                         using var json = await JsonDocument.ParseAsync(response.ContentStream);
                         var info = json.ToObject<OpenApp>();
                         //创建Token
-                        var auth_token = JwtAuthExtension.CreateAppToken(_option.HostName, info.id, _option.JwtSecretKey, info.school);
+                        //域名  应用的id, jwtkey  学校编码
+                        var auth_token = JwtAuthExtension.CreateApiToken(_option.HostName, info.id, _option.JwtSecretKey, info.name, info.school);
                         info.token = auth_token;
                         info = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(info, info.id, new PartitionKey($"{info.code}"));
                         return Ok(new { auth_token });

+ 2 - 2
TEAMModelOS/Controllers/Teacher/InitController.cs

@@ -389,7 +389,7 @@ namespace TEAMModelOS.Controllers
         /// <param name="requert"></param>
         /// <returns></returns>
         [ProducesDefaultResponseType]
-        //[AuthToken(Roles = "teacher")]
+        [AuthToken(Roles = "teacher")]
         [HttpPost("join-school")]
         public async Task<IActionResult> JoinSchool(JsonElement requert)
         {
@@ -444,7 +444,7 @@ namespace TEAMModelOS.Controllers
                     var response = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(st, new PartitionKey($"Teacher-{school_code}"));
                 }
 
-                return Ok();
+                return Ok(new { stauts=1});
             }
             catch (Exception ex)
             {

+ 75 - 0
TEAMModelOS/Filter/ApiTokenAttribute.cs

@@ -0,0 +1,75 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using TEAMModelOS.SDK.Extension;
+using System;
+using TEAMModelOS.Models;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.DependencyInjection;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+
+namespace TEAMModelOS.Filter
+{
+    public class ApiTokenAttribute : Attribute, IFilterFactory
+    {
+        public bool IsReusable => true;
+        //public string Roles { get; set; }
+        //public string Permissions { get; set; }
+
+        public IFilterMetadata CreateInstance(IServiceProvider services)
+        {
+            var option = services.GetService<IOptions<Option>>();
+            return new InternalAuthTokenFilter(option);
+        }
+
+        private class InternalAuthTokenFilter : IResourceFilter
+        {
+            private readonly Option _option;
+            //private readonly string _roles;
+            //private readonly string _permissions;
+
+            public InternalAuthTokenFilter(IOptions<Option> option)
+            {
+                _option = option.Value;
+                //_roles = roles;
+                //_permissions = permissions;
+            }
+            public void OnResourceExecuting(ResourceExecutingContext context)
+            {
+                bool pass = false;
+                string id = string.Empty, name = string.Empty, school = string.Empty,jti=string.Empty;
+
+                var authtoken = context.HttpContext.GetXAuth("ApiToken");
+                if (!string.IsNullOrWhiteSpace(authtoken) && JwtAuthExtension.ValidateApiToken(authtoken, _option.JwtSecretKey))
+                {
+                    var jwt = new JwtSecurityTokenHandler().ReadJwtToken(authtoken);
+                    id = jwt.Payload.Sub;
+                    school = jwt.Payload.Azp;
+                    jti = jwt.Payload.Jti;
+                    name = jwt.Claims.FirstOrDefault(claim => claim.Type == "name")?.Value;
+                    //处理限流问题
+                    if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(school) || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(jti))
+                    {
+                        context.Result = new BadRequestResult();
+                    }
+                    else { 
+                        
+                    }
+                }
+
+                if (pass)
+                {
+                    context.HttpContext.Items.Add("ID", id);
+                    context.HttpContext.Items.Add("Name", name);
+                    context.HttpContext.Items.Add("School", school);
+                }
+                else
+                    context.Result = new BadRequestResult();
+            }
+
+            public void OnResourceExecuted(ResourceExecutedContext context)
+            {
+            }
+        }
+    }
+}

+ 0 - 3
TEAMModelOS/appsettings.Development.json

@@ -27,9 +27,6 @@
       "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
       //"ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"
     },
-    "CosmosDep": {
-      "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
-    },
     "Redis": {
       "ConnectionString": "106.12.23.251:6379,password=habook,ssl=false,abortConnect=False,writeBuffer=10240"
       //"ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False"