Exemplo n.º 1
0
        /// <summary>
        /// 本地执行方法
        /// </summary>
        /// <param name="serviceEntry"></param>
        /// <param name="invokeMessage"></param>
        /// <param name="resultMessage"></param>
        /// <returns></returns>
        private async Task LocalServiceExecuteAsync(RemoteExecutorContext context, RemoteCallBackData resultMessage)
        {
            try
            {
                CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
                if (!cancelTokenSource.IsCancellationRequested)
                {
                    object result = await context.ServiceEntry.Func(context);

                    Task task = result as Task;
                    if (task == null)
                    {
                        resultMessage.Result = result;
                    }
                    else
                    {
                        task.Wait(cancelTokenSource.Token);
                        TypeInfo taskType = task.GetType().GetTypeInfo();
                        if (taskType.IsGenericType)
                        {
                            resultMessage.Result = taskType.GetProperty("Result")?.GetValue(task);
                        }
                    }
                    resultMessage.ResultType = context.ServiceEntry.Descriptor.ReturnDesc;
                }
            }
            catch (Exception ex)
            {
                _logger.Error("throw exception when excuting local service: " + context.ServiceEntry.Descriptor.Id, ex);
                resultMessage.ExceptionMessage = ex.Message;
            }
        }
Exemplo n.º 2
0
        private async Task OnReceived(IChannelHandlerContext channel, TransportMsg message)
        {
            _logger.Debug($"开始触发服务: {message.Id}");
            if (message.ContentType == typeof(RemoteCallData).FullName)
            {
                IResponse             response    = new RpcResponse(channel, _serializer, _logger);
                RemoteExecutorContext thisContext = new RemoteExecutorContext(message, _serviceEntryContainer, response, _serializer, _logger, _serviceDiscovery);

                RequestDel lastInvoke = new RequestDel(async context =>
                {
                    RemoteCallBackData resultMessage = new RemoteCallBackData();
                    if (context.ServiceEntry == null)
                    {
                        resultMessage.ExceptionMessage = $"没有此服务:{context.RemoteInvokeMessage.ServiceId}";
                        await response.WriteAsync(message.Id, resultMessage);
                    }
                    else if (context.ServiceEntry.Descriptor.WaitExecution)
                    {
                        await LocalServiceExecuteAsync(context, resultMessage);
                        await response.WriteAsync(message.Id, resultMessage);
                    }
                    else
                    {
                        await response.WriteAsync(message.Id, resultMessage);
                        await Task.Factory.StartNew(async() =>
                        {
                            await LocalServiceExecuteAsync(context, resultMessage);
                        });
                    }
                });

                foreach (Func <RequestDel, RequestDel> middleware in _middlewares)
                {
                    lastInvoke = middleware.Invoke(lastInvoke);
                }
                await lastInvoke.Invoke(thisContext);
            }
            else
            {
                _logger.Debug($"msg: {message.Id}, message type is not an  RemoteCallData.");
            }
        }
Exemplo n.º 3
0
        public Task Invoke(RemoteExecutorContext context)
        {
            // get jwt token
            if (!string.IsNullOrEmpty(_options.TokenEndpointPath) &&
                context.ServiceEntry == null &&
                context.RemoteInvokeMessage.ServiceId == _options.TokenEndpointPath.TrimStart('/'))
            {
                if (_options.CheckCredential == null)
                {
                    throw new Exception("JwtAuthorizationOptions.CheckCredential must be provided");
                }

                JwtAuthorizationContext jwtAuthorizationContext = new JwtAuthorizationContext(_options, context.RemoteInvokeMessage);

                _options.CheckCredential(jwtAuthorizationContext);
                if (jwtAuthorizationContext.IsRejected)
                {
                    return(context.Response.WriteAsync(context.TransportMessage.Id, new RemoteCallBackData
                    {
                        ErrorMsg = $"{jwtAuthorizationContext.Error}, {jwtAuthorizationContext.ErrorDescription}",
                        ErrorCode = "400"
                    }));
                }

                Dictionary <string, object> payload = jwtAuthorizationContext.GetPayload();
                IJwtAlgorithm     algorithm         = new HMACSHA256Algorithm();
                IJsonSerializer   serializer        = new JsonNetSerializer();
                IBase64UrlEncoder urlEncoder        = new JwtBase64UrlEncoder();
                IJwtEncoder       encoder           = new JwtEncoder(algorithm, serializer, urlEncoder);
                string            token             = encoder.Encode(payload, _options.SecretKey);

                IDictionary <string, object> result = new Dictionary <string, object>
                {
                    ["access_token"] = token
                };
                if (_options.ValidateLifetime)
                {
                    result["expired_in"] = payload["exp"];
                }

                return(context.Response.WriteAsync(context.TransportMessage.Id, new RemoteCallBackData
                {
                    Result = result
                }));
            }
            else if (context.ServiceEntry != null && context.ServiceEntry.Descriptor.EnableAuthorization)
            {
                try
                {
                    string pureToken = context.RemoteInvokeMessage.Token;
                    if (pureToken != null && pureToken.Trim().StartsWith("Bearer "))
                    {
                        pureToken = pureToken.Trim().Substring(6).Trim();
                    }
                    else
                    {
                        return(context.Response.WriteAsync(context.TransportMessage.Id, Unauthorized("Unauthorized")));
                    }

                    IJsonSerializer   serializer = new JsonNetSerializer();
                    IDateTimeProvider provider   = new UtcDateTimeProvider();
                    IJwtValidator     validator  = new JwtValidator(serializer, provider);
                    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                    IJwtDecoder       decoder    = new JwtDecoder(serializer, validator, urlEncoder);
                    string            payload    = decoder.Decode(pureToken, _options.SecretKey, verify: true);

                    IDictionary <string, object> payloadObj = _serializer.Deserialize <string, Dictionary <string, object> >(payload);
                    if (_options.ValidateLifetime)
                    {
                        //var exp = payloadObj["exp"];
                        if (payloadObj == null || (long.Parse(payloadObj["exp"].ToString()).ToDate() < DateTime.Now))
                        {
                            return(context.Response.WriteAsync(context.TransportMessage.Id, Unauthorized("Token is Expired")));
                        }
                    }
                    string serviceRoles = context.ServiceEntry.Descriptor.Roles;
                    if (!string.IsNullOrEmpty(serviceRoles))
                    {
                        string[] serviceRoleArr = serviceRoles.Split(',');
                        string   roles          = payloadObj != null && payloadObj.ContainsKey("roles") ? payloadObj["roles"] + "" : "";
                        bool     authorize      = roles.Split(',').Any(role => serviceRoleArr.Any(x => x.Equals(role, StringComparison.InvariantCultureIgnoreCase)));
                        if (!authorize)
                        {
                            return(context.Response.WriteAsync(context.TransportMessage.Id, Unauthorized("Unauthorized")));
                        }
                    }
                    context.RemoteInvokeMessage.Payload = new Payload {
                        Items = payloadObj
                    };
                }
                catch (Exception ex)
                {
                    return(context.Response.WriteAsync(context.TransportMessage.Id, Unauthorized($"Token is incorrect, exception is { ex.Message}")));
                }
                return(_next(context));
            }
            // service can be annoymouse request

            return(_next(context));
        }