private async Task <ServiceRoute> LocationServiceRoute(string routePath, string httpMethod)
        {
            var serviceRoute = await _serviceRouteProvider.GetRouteByPathOrRegexPath(routePath.ToLower(), httpMethod);

            if (serviceRoute == null)
            {
                throw new CPlatformException($"不存在api为{routePath}的路由信息");
            }

            return(serviceRoute);
        }
Exemplo n.º 2
0
            protected override void ChannelRead0(IChannelHandlerContext ctx, IFullHttpRequest msg)
            {
                var data = new byte[msg.Content.ReadableBytes];

                msg.Content.ReadBytes(data);

                Task.Run(async() =>
                {
                    var parameters   = GetParameters(HttpUtility.UrlDecode(msg.Uri), out string path);
                    path             = AppConfig.MapRoutePathOptions.GetRoutePath(path, msg.Method.Name);
                    var serviceRoute = await _serviceRouteProvider.GetRouteByPathOrRegexPath(path, msg.Method.Name.ToUpper());
                    if (serviceRoute == null)
                    {
                        throw new CPlatformException($"未能找到路径为{path}-{msg.Method.Name.ToUpper()}的路由信息", StatusCode.Http404EndpointStatusCode);
                    }
                    parameters.Remove("servicekey", out object serviceKey);
                    if (data.Length > 0)
                    {
                        parameters = _serializer.Deserialize <string, IDictionary <string, object> >(System.Text.Encoding.ASCII.GetString(data)) ?? new Dictionary <string, object>();
                    }
                    if (String.Compare(serviceRoute.ServiceDescriptor.RoutePath, path, true) != 0)
                    {
                        var @params = RouteTemplateSegmenter.Segment(serviceRoute.ServiceDescriptor.RoutePath, path);
                        foreach (var param in @params)
                        {
                            parameters.Add(param.Key, param.Value);
                        }
                    }
                    if (msg.Method.Name == "POST")
                    {
                        _readAction(ctx, new TransportMessage(new HttpMessage
                        {
                            Parameters = parameters,
                            RoutePath  = serviceRoute.ServiceDescriptor.RoutePath,
                            HttpMethod = msg.Method.Name.ToUpper(),
                            ServiceKey = serviceKey?.ToString()
                        }));
                    }
                    else
                    {
                        _readAction(ctx, new TransportMessage(new HttpMessage
                        {
                            Parameters = parameters,
                            RoutePath  = serviceRoute.ServiceDescriptor.RoutePath,
                            HttpMethod = msg.Method.Name.ToUpper(),
                            ServiceKey = serviceKey?.ToString()
                        }));
                    }
                });
            }
        public  async Task OnActionExecuting(ActionExecutingContext filterContext)
        { 
            var serviceEntry= _serviceEntryLocate.Locate(filterContext.Message);
            if (serviceEntry != null)
            {
                var httpMethods = serviceEntry.Methods;
                if (httpMethods.Count()>0 && !httpMethods.Any(p => String.Compare(p, filterContext.Context.Request.Method, true) == 0))
                {
                    filterContext.Result = new HttpResultMessage<object>
                    {
                        IsSucceed = false,
                        StatusCode = Http405EndpointStatusCode,
                        Message = Http405EndpointDisplayName
                    };
                }
            }
            else
            {
                var path = HttpUtility.UrlDecode(GetRoutePath(filterContext.Context.Request.Path.ToString()));
                path = AppConfig.MapRoutePathOptions.GetRoutePath(path, filterContext.Message.HttpMethod);
                var serviceRoute = await _serviceRouteProvider.GetRouteByPathOrRegexPath(path, filterContext.Message.HttpMethod);
                if (serviceRoute == null)
                {
                    throw new CPlatformException($"未能找到路径为{path}-{filterContext.Message.HttpMethod}的路由信息", StatusCode.Http404EndpointStatusCode);
                }

                var httpMethods = serviceRoute.ServiceDescriptor.HttpMethod();
                if (httpMethods != null && !httpMethods.Contains(filterContext.Context.Request.Method))
                {
                    filterContext.Result = new HttpResultMessage<object>
                    {
                        IsSucceed = false,
                        StatusCode = Http405EndpointStatusCode,
                        Message = Http405EndpointDisplayName
                    };
                }
            }
        }
Exemplo n.º 4
0
        public async Task OnAuthorization(AuthorizationFilterContext filterContext)
        {
            var gatewayAppConfig = AppConfig.Options.ApiGetWay;

            if (filterContext.Route != null && filterContext.Route.ServiceDescriptor.DisableNetwork())
            {
                var actionName = filterContext.Route.ServiceDescriptor.GroupName().IsNullOrEmpty()
                    ? filterContext.Route.ServiceDescriptor.RoutePath
                    : filterContext.Route.ServiceDescriptor.GroupName();
                filterContext.Result = new HttpResultMessage <object>
                {
                    IsSucceed = false, StatusCode = CPlatform.Exceptions.StatusCode.UnAuthorized,
                    Message   = $"{actionName}禁止被外网访问"
                };
            }
            else
            {
                var token = filterContext.Context.Request.Headers["Authorization"];

                if (filterContext.Route != null)
                {
                    if (filterContext.Route.ServiceDescriptor.AuthType() == AuthorizationType.JWT.ToString())
                    {
                        if (token.Any() && token.Count >= 1)
                        {
                            var validateResult = _authorizationServerProvider.ValidateClientAuthentication(token);
                            if (filterContext.Route.ServiceDescriptor.EnableAuthorization() &&
                                validateResult != ValidateResult.Success)
                            {
                                if (validateResult == ValidateResult.TokenFormatError)
                                {
                                    filterContext.Result = new HttpResultMessage <object>
                                    {
                                        IsSucceed  = false,
                                        StatusCode = CPlatform.Exceptions.StatusCode.UnAuthentication,
                                        Message    = "token格式不正确"
                                    };
                                    return;
                                }

                                if (validateResult == ValidateResult.SignatureError)
                                {
                                    filterContext.Result = new HttpResultMessage <object>
                                    {
                                        IsSucceed  = false,
                                        StatusCode = CPlatform.Exceptions.StatusCode.UnAuthentication,
                                        Message    = "token凭证不合法,请重新登录"
                                    };
                                    return;
                                }

                                if (validateResult == ValidateResult.TokenExpired)
                                {
                                    filterContext.Result = new HttpResultMessage <object>
                                    {
                                        IsSucceed = false, StatusCode = CPlatform.Exceptions.StatusCode.TokenExpired,
                                        Message   = "登录超时,请重新登录"
                                    };
                                    return;
                                }
                            }

                            var payload = _authorizationServerProvider.GetPayload(token);

                            var claimsIdentity = new ClaimsIdentity();

                            foreach (var item in payload)
                            {
                                claimsIdentity.AddClaim(new Claim(item.Key, item.Value.ToString()));
                            }

                            if (!gatewayAppConfig.AuthorizationRoutePath.IsNullOrEmpty() &&
                                filterContext.Route.ServiceDescriptor.EnableAuthorization())
                            {
                                var rpcParams = new Dictionary <string, object>()
                                {
                                    { "serviceId", filterContext.Route.ServiceDescriptor.Id }
                                };
                                var authorizationRoutePath =
                                    await _serviceRouteProvider.GetRouteByPathOrRegexPath(
                                        gatewayAppConfig.AuthorizationRoutePath, HttpMethod.POST.ToString());

                                if (authorizationRoutePath == null)
                                {
                                    filterContext.Result = new HttpResultMessage <object>
                                    {
                                        IsSucceed = false, StatusCode = CPlatform.Exceptions.StatusCode.RequestError,
                                        Message   = "没有找到实现接口鉴权的WebApi的路由信息"
                                    };
                                    return;
                                }

                                foreach (var kv in payload)
                                {
                                    RpcContext.GetContext().SetAttachment(kv.Key, kv.Value);
                                }

                                var checkPermissionResult =
                                    await _serviceProxyProvider.Invoke <IDictionary <string, object> >(rpcParams,
                                                                                                       gatewayAppConfig.AuthorizationRoutePath, HttpMethod.POST,
                                                                                                       gatewayAppConfig.AuthorizationServiceKey);

                                if (checkPermissionResult == null || !checkPermissionResult.ContainsKey("isPermission"))
                                {
                                    filterContext.Result = new HttpResultMessage <object>
                                    {
                                        IsSucceed = false, StatusCode = StatusCode.UnAuthorized,
                                        Message   = $"接口鉴权返回数据格式错误,鉴权接口返回数据格式必须为字典,且必须包含IsPermission的key"
                                    };
                                    return;
                                }

                                var isPermission = Convert.ToBoolean(checkPermissionResult["isPermission"]);
                                if (!isPermission)
                                {
                                    var actionName = filterContext.Route.ServiceDescriptor.GroupName().IsNullOrEmpty()
                                        ? filterContext.Route.ServiceDescriptor.RoutePath
                                        : filterContext.Route.ServiceDescriptor.GroupName();
                                    filterContext.Result = new HttpResultMessage <object>
                                    {
                                        IsSucceed = false, StatusCode = StatusCode.UnAuthorized,
                                        Message   = $"没有请求{actionName}的权限"
                                    };
                                    return;
                                }

                                foreach (var kv in checkPermissionResult)
                                {
                                    if (kv.Key == "isPermission")
                                    {
                                        continue;
                                    }

                                    if (kv.Value == null)
                                    {
                                        continue;
                                    }

                                    claimsIdentity.AddClaim(new Claim(kv.Key, kv.Value.ToString()));
                                }
                            }

                            filterContext.Context.User = new ClaimsPrincipal(claimsIdentity);
                        }
                        else
                        {
                            if (filterContext.Route.ServiceDescriptor.EnableAuthorization())
                            {
                                filterContext.Result = new HttpResultMessage <object>
                                {
                                    IsSucceed = false, StatusCode = CPlatform.Exceptions.StatusCode.UnAuthentication,
                                    Message   = $"请先登录系统"
                                };
                                return;
                            }
                            else
                            {
                                filterContext.Context.User = null;
                            }
                        }
                    }
                    else
                    {
                        if (filterContext.Route.ServiceDescriptor.EnableAuthorization())
                        {
                            filterContext.Result = new HttpResultMessage <object>
                            {
                                IsSucceed = false, StatusCode = CPlatform.Exceptions.StatusCode.UnAuthentication,
                                Message   = $"暂不支持{filterContext.Route.ServiceDescriptor.AuthType()}类型的身份认证方式"
                            };
                        }
                    }
                }
            }

            if (string.Compare(filterContext.Path.ToLower(), gatewayAppConfig.TokenEndpointPath, true) == 0)
            {
                filterContext.Context.Items.Add("path", gatewayAppConfig.AuthenticationRoutePath);
            }
        }
        public async Task OnReceived(IMessageSender sender, string messageId, HttpContext context, IEnumerable <IActionFilter> actionFilters)
        {
            var serviceRoute = context.Items["route"] as ServiceRoute;

            var path = (context.Items["path"]
                        ?? HttpUtility.UrlDecode(GetRoutePath(context.Request.Path.ToString()))) as string;

            path = AppConfig.MapRoutePathOptions.GetRoutePath(path, context.Request.Method);
            if (serviceRoute == null)
            {
                var route = await _serviceRouteProvider.GetRouteByPathOrRegexPath(path, context.Request.Method);

                if (route == null)
                {
                    throw new CPlatformException($"未能找到路径为{path}-{context.Request.Method}的路由信息", StatusCode.Http404EndpointStatusCode);
                }
                serviceRoute = route;
            }
            IDictionary <string, object> parameters = context.Request.Query.ToDictionary(p => p.Key, p => (object)p.Value.ToString());
            object serviceKey = null;

            foreach (var key in _serviceKeys)
            {
                parameters.Remove(key, out object value);
                if (value != null)
                {
                    serviceKey = value;
                    break;
                }
            }

            if (!serviceRoute.ServiceDescriptor.RoutePath.Equals(path, StringComparison.OrdinalIgnoreCase))
            {
                var @params = RouteTemplateSegmenter.Segment(serviceRoute.ServiceDescriptor.RoutePath, path);
                foreach (var param in @params)
                {
                    parameters.Add(param.Key, param.Value);
                }
            }

            var httpMessage = new HttpMessage
            {
                Parameters = parameters,
                RoutePath  = serviceRoute.ServiceDescriptor.RoutePath,
                HttpMethod = context.Request.Method,
                ServiceKey = serviceKey?.ToString()
            };

            if (context.Request.HasFormContentType)
            {
                if (context.Request.ContentType == "multipart/form-data")
                {
                    var collection = await GetFormCollection(context.Request);

                    httpMessage.Parameters.Add("form", collection);
                }
                else
                {
                    var formData = new Dictionary <string, object>();
                    foreach (var item in context.Request.Form.Keys)
                    {
                        formData.Add(item, context.Request.Form[item]);
                    }

                    httpMessage.Parameters.Add("form", formData);
                }

                if (!await OnActionExecuting(new ActionExecutingContext {
                    Context = context, Route = serviceRoute, Message = httpMessage
                },
                                             sender, messageId, actionFilters))
                {
                    return;
                }
                httpMessage.Attachments = GetHttpMessageAttachments(context);
                await Received(sender, new TransportMessage(messageId, httpMessage));
            }
            else
            {
                StreamReader streamReader = new StreamReader(context.Request.Body);
                var          data         = await streamReader.ReadToEndAsync();

                if (context.Request.Method != "GET")
                {
                    var bodyParams = _serializer.Deserialize <string, IDictionary <string, object> >(data) ?? new Dictionary <string, object>();
                    foreach (var param in bodyParams)
                    {
                        httpMessage.Parameters.Add(param.Key, param.Value);
                    }
                    if (!await OnActionExecuting(new ActionExecutingContext {
                        Context = context, Route = serviceRoute, Message = httpMessage
                    },
                                                 sender, messageId, actionFilters))
                    {
                        return;
                    }
                    httpMessage.Attachments = GetHttpMessageAttachments(context);
                    await Received(sender, new TransportMessage(messageId, httpMessage));
                }
                else
                {
                    if (!await OnActionExecuting(new ActionExecutingContext {
                        Context = context, Route = serviceRoute, Message = httpMessage
                    },
                                                 sender, messageId, actionFilters))
                    {
                        return;
                    }
                    httpMessage.Attachments = GetHttpMessageAttachments(context);
                    await Received(sender, new TransportMessage(messageId, httpMessage));
                }
            }



            await OnActionExecuted(context, httpMessage, actionFilters);
        }