/// <summary> /// Processes the route. /// </summary> /// <param name="context">The context.</param> /// <param name="doAuthentication">if set to <c>true</c> [do authentication].</param> /// <returns></returns> /// <exception cref="ResourceNotFoundException"> /// ResourceName /// or /// or /// </exception> internal virtual RuntimeContext ProcessRoute(HttpApiContextContainer <TRequest, TResponse> context, bool doAuthentication = true) { try { context.CheckNullObject(nameof(context)); var httpMethod = context.HttpMethod; var uri = context.Url; var rawFullUrl = string.Format("{0}: {1}", httpMethod, context.Url); var result = InitializeRuntimeContext(uri); result.CheckNullObjectAsInvalid("URL"); if (result.Version.Equals(ApiConstants.BuiltInFeatureVersionKeyword, StringComparison.OrdinalIgnoreCase)) { return(result); } if (string.IsNullOrWhiteSpace(result.ResourceName)) { throw new ResourceNotFoundException(rawFullUrl, nameof(result.ResourceName)); } RuntimeRoute runtimeRoute; var apiRouterIdentifier = new ApiRouteIdentifier(result.Realm, result.Version, result.ResourceName, httpMethod, result.Parameter1); if (!RestApiRoutePool.Routes.TryGetValue(apiRouterIdentifier, out runtimeRoute)) { apiRouterIdentifier = new ApiRouteIdentifier(result.Realm, result.Version, result.ResourceName, httpMethod, null); RestApiRoutePool.Routes.TryGetValue(apiRouterIdentifier, out runtimeRoute); } else { if (runtimeRoute != null && (!string.IsNullOrWhiteSpace(result.Parameter1) && !runtimeRoute.IsActionUsed)) { throw new ResourceNotFoundException(rawFullUrl); } } if (runtimeRoute == null) { throw new ResourceNotFoundException(rawFullUrl); } result.ApiRouterIdentifier = apiRouterIdentifier; // Override out parameters result.OperationParameters = runtimeRoute.OperationParameters ?? new RuntimeApiOperationParameters(); result.ApiMethod = runtimeRoute.ApiMethod; result.ApiInstance = runtimeRoute.ApiInstance; result.IsActionUsed = runtimeRoute.IsActionUsed; result.IsVoid = runtimeRoute.IsVoid; context.Settings = result.Settings = runtimeRoute.Setting ?? RestApiSettingPool.DefaultRestApiSettings; result.OmitApiEvent = runtimeRoute.OmitApiTracking?.Omit(ApiTrackingType.Event) ?? false; if (runtimeRoute.ApiCacheAttribute != null) { result.ApiCacheIdentity = runtimeRoute.ApiRouteIdentifier.Clone() as ApiRouteIdentifier; if (runtimeRoute.ApiCacheAttribute.CacheParameter.CachedByParameterizedIdentity) { result.ApiCacheIdentity.SetParameterizedIdentifier(uri.ToQueryString()); } result.ApiCacheContainer = runtimeRoute.ApiCacheContainer; if (result.ApiCacheContainer != null) { string cachedResponseBody; if (result.ApiCacheContainer.GetCacheResult(result.ApiCacheIdentity, out cachedResponseBody)) { result.CachedResponseBody = cachedResponseBody; result.ApiCacheStatus = ApiCacheStatus.UseCache; } else { result.ApiCacheStatus = ApiCacheStatus.UpdateCache; } } else { result.ApiCacheStatus = ApiCacheStatus.NoCache; } } // Fill basic context info. var userAgentHeaderKey = context.Settings?.OriginalUserAgentHeaderKey; var token = context.TryGetRequestHeader((context.Settings?.TokenHeaderKey).SafeToString(HttpConstants.HttpHeader.TOKEN)); ContextHelper.ApiContext.IndicatedOperator = context.TryGetRequestHeader(HttpConstants.HttpHeader.OPERATOR); ContextHelper.ConsistContext( // TOKEN token, // Settings context.Settings, // IP Address context.TryGetRequestHeader(context.Settings?.OriginalIpAddressHeaderKey.SafeToString(HttpConstants.HttpHeader.ORIGINAL)).SafeToString(context.ClientIpAddress), // User Agent string.IsNullOrWhiteSpace(userAgentHeaderKey) ? context.UserAgent : context.TryGetRequestHeader(userAgentHeaderKey).SafeToString(context.UserAgent), // Culture Code context.QueryString.Get(HttpConstants.QueryString.Language).SafeToString(context.UserLanguages.SafeFirstOrDefault()).EnsureCultureCode(), // Current Uri context.Url, HttpExtension.GetBasicAuthentication(context.TryGetRequestHeader(HttpConstants.HttpHeader.Authorization).DecodeBase64()), apiRouterIdentifier.ToApiUniqueIdentifier() ); string userIdentifier = ContextHelper.ApiContext.CurrentCredential?.Name.SafeToString(token); var authenticationException = doAuthentication ? Authorize(runtimeRoute, ContextHelper.ApiContext) : null; if (authenticationException != null) { throw authenticationException.Handle(new { result.ApiMethod.Name, token }); } return(result); } catch (Exception ex) { throw ex.Handle(); } }
/// <summary> /// Called by the ASP.NET MVC framework before the action method executes. /// </summary> /// <param name="filterContext">The filter context.</param> public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); IsOptions = HandleOptionsRequests(filterContext); if (Depth < 1) { Depth = 0; ContextHelper.Reinitialize(); DateTime entryStamp = DateTime.UtcNow; var request = filterContext.HttpContext.Request; var traceId = request.TryGetHeader(HttpConstants.HttpHeader.TRACEID); var traceSequence = request.TryGetHeader(HttpConstants.HttpHeader.TRACESEQUENCE).ObjectToNullableInt32(); var methodInfo = (filterContext.ActionDescriptor as ReflectedActionDescriptor)?.MethodInfo; var httpContextContainer = new HttpBaseApiContextContainer(request, filterContext.HttpContext.Response); ContextHelper.ConsistContext(httpContextContainer, settings); WebThreadPool.Register(); if (!string.IsNullOrWhiteSpace(traceId)) { ApiTraceContext.Initialize(traceId, traceSequence, entryStamp); } if (settings != null && settings.TrackingEvent) { var context = filterContext.HttpContext; ApiEvent = new ApiEventLog { RawUrl = context.Request.RawUrl, EntryStamp = entryStamp, TraceId = traceId, // If request came from ApiTransport or other proxy ways, ORIGINAL stands for the IP ADDRESS from original requester. IpAddress = context.Request.TryGetHeader(settings?.OriginalIpAddressHeaderKey.SafeToString(HttpConstants.HttpHeader.ORIGINAL)).SafeToString(context.Request.UserHostAddress), CultureCode = ContextHelper.ApiContext.CultureCode, ContentLength = context.Request.ContentLength, OperatorCredential = ContextHelper.CurrentCredential as BaseCredential, ServerIdentifier = EnvironmentCore.MachineName, ServiceIdentifier = EnvironmentCore.ProductName }; } var controllerType = methodInfo?.DeclaringType; var tokenRequiredAttribute = methodInfo?.GetCustomAttribute <TokenRequiredAttribute>(true) ?? controllerType?.GetCustomAttribute <TokenRequiredAttribute>(true); var permissionAttributes = controllerType?.GetCustomAttributes <ApiPermissionAttribute>(true).ToDictionary(); permissionAttributes.Merge(methodInfo?.GetCustomAttributes <ApiPermissionAttribute>(true).ToDictionary(), true); var tokenRequired = tokenRequiredAttribute != null && tokenRequiredAttribute.TokenRequired; if (tokenRequired) { if (ContextHelper.CurrentCredential == null) { var baseException = (new UnauthorizedTokenException(ContextHelper.Token)).Handle( filterContext.HttpContext.Request.ToExceptionScene(filterContext.RouteData?.GetControllerName()), data: new { filterContext.HttpContext.Request.RawUrl }); HandleUnauthorizedAction(filterContext, baseException); } else if (permissionAttributes.HasItem()) { var baseException = ContextHelper.CurrentUserInfo?.Permissions.ValidateApiPermission(permissionAttributes, ContextHelper.Token, methodInfo?.GetFullName()); if (baseException != null) { HandleUnauthorizedAction(filterContext, baseException); } } } ApiTraceContext.Enter(methodInfo.GetFullName(), setNameAsMajor: true); } Depth++; }