/// <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; } }
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."); } }
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)); }