DenyAccess() public static method

public static DenyAccess ( System.Web.HttpApplication application ) : void
application System.Web.HttpApplication
return void
Esempio n. 1
0
        internal void AuthorizeRequest(HttpContext context)
        {
            PortalContext currentPortalContext = PortalContext.Current;

            if (currentPortalContext == null)
            {
                return;
            }
            var currentUser = context?.User.Identity as User;

            // deny access for visitors in case of webdav or office protocol requests, if they have no See access to the content
            if (currentUser != null && currentUser.Id == Identifiers.VisitorUserId && (currentPortalContext.IsOfficeProtocolRequest || currentPortalContext.IsWebdavRequest))
            {
                if (!currentPortalContext.IsRequestedResourceExistInRepository ||
                    currentPortalContext.ContextNodeHead == null ||
                    !SecurityHandler.HasPermission(currentPortalContext.ContextNodeHead, PermissionType.See))
                {
                    AuthenticationHelper.ForceBasicAuthentication(HttpContext.Current);
                }
            }

            if (context == null)
            {
                return;
            }

            if (currentPortalContext.IsRequestedResourceExistInRepository)
            {
                var authMode = currentPortalContext.AuthenticationMode;
                if (string.IsNullOrEmpty(authMode))
                {
                    authMode = WebApplication.DefaultAuthenticationMode;
                }

                bool appPerm;
                if (authMode == "Forms")
                {
                    appPerm = currentPortalContext.CurrentAction.CheckPermission();
                }
                else if (authMode == "Windows")
                {
                    currentPortalContext.CurrentAction.AssertPermissions();
                    appPerm = true;
                }
                else
                {
                    throw new NotSupportedException("None authentication is not supported");
                }

                var path            = currentPortalContext.RepositoryPath;
                var nodeHead        = NodeHead.Get(path);
                var permissionValue = SecurityHandler.GetPermission(nodeHead, PermissionType.Open);

                if (permissionValue == PermissionValue.Allowed && DocumentPreviewProvider.Current.IsPreviewOrThumbnailImage(nodeHead))
                {
                    // In case of preview images we need to make sure that they belong to a content version that
                    // is accessible by the user (e.g. must not serve images for minor versions if the user has
                    // access only to major versions of the content).
                    if (!DocumentPreviewProvider.Current.IsPreviewAccessible(nodeHead))
                    {
                        permissionValue = PermissionValue.Denied;
                    }
                }
                else if (permissionValue != PermissionValue.Allowed && appPerm && DocumentPreviewProvider.Current.HasPreviewPermission(nodeHead))
                {
                    // In case Open permission is missing: check for Preview permissions. If the current Document
                    // Preview Provider allows access to a preview, we should allow the user to access the content.
                    permissionValue = PermissionValue.Allowed;
                }

                if (permissionValue != PermissionValue.Allowed)
                {
                    if (nodeHead.Id == Identifiers.PortalRootId)
                    {
                        if (currentPortalContext.IsOdataRequest)
                        {
                            if (currentPortalContext.ODataRequest.IsMemberRequest)
                            {
                                permissionValue = PermissionValue.Allowed;
                            }
                        }
                    }
                }

                if (permissionValue != PermissionValue.Allowed || !appPerm)
                {
                    if (currentPortalContext.IsOdataRequest)
                    {
                        AuthenticationHelper.ThrowForbidden();
                    }
                    switch (authMode)
                    {
                    case "Forms":
                        if (User.Current.IsAuthenticated)
                        {
                            // user is authenticated, but has no permissions: return 403
                            context.Response.StatusCode = 403;
                            context.Response.Flush();
                            context.Response.Close();
                        }
                        else
                        {
                            // let webdav and office protocol handle authentication - in these cases redirecting to a login page makes no sense
                            if (PortalContext.Current.IsWebdavRequest || PortalContext.Current.IsOfficeProtocolRequest)
                            {
                                return;
                            }

                            // user is not authenticated and visitor has no permissions: redirect to login page
                            // Get the login page Url (eg. http://localhost:1315/home/login)
                            string loginPageUrl = currentPortalContext.GetLoginPageUrl();
                            // Append trailing slash
                            if (loginPageUrl != null && !loginPageUrl.EndsWith("/"))
                            {
                                loginPageUrl = loginPageUrl + "/";
                            }

                            // Cut down the querystring (eg. drop ?Param1=value1@Param2=value2)
                            string currentRequestUrlWithoutQueryString = currentPortalContext.RequestedUri.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.Unescaped);

                            // Append trailing slash
                            if (!currentRequestUrlWithoutQueryString.EndsWith("/"))
                            {
                                currentRequestUrlWithoutQueryString = currentRequestUrlWithoutQueryString + "/";
                            }

                            // Redirect to the login page, if neccessary.
                            if (currentRequestUrlWithoutQueryString != loginPageUrl)
                            {
                                context.Response.Redirect(loginPageUrl + "?OriginalUrl=" + System.Web.HttpUtility.UrlEncode(currentPortalContext.RequestedUri.ToString()), true);
                            }
                        }
                        break;

                    default:
                        AuthenticationHelper.DenyAccess(context);
                        break;
                    }
                }
            }
        }
Esempio n. 2
0
        private void EmulateWindowsAuthentication(HttpApplication application)
        {
            WindowsIdentity identity = null;

            if (HttpRuntime.UsingIntegratedPipeline)
            {
                WindowsPrincipal user = null;
                if (HttpRuntime.IsOnUNCShare && application.Request.IsAuthenticated)
                {
                    IntPtr applicationIdentityToken = (IntPtr)typeof(System.Web.Hosting.HostingEnvironment).GetProperty("ApplicationIdentityToken", BindingFlags.NonPublic | BindingFlags.Static).GetGetMethod().Invoke(null, null);

                    WindowsIdentity wi = new WindowsIdentity(applicationIdentityToken, application.User.Identity.AuthenticationType, WindowsAccountType.Normal, true);

                    user = new WindowsPrincipal(wi);
                }
                else
                {
                    user = application.Context.User as WindowsPrincipal;
                }

                if (user != null)
                {
                    identity = user.Identity as WindowsIdentity;

                    object[]   setPrincipalNoDemandParameters     = new object[] { null, false };
                    Type[]     setPrincipalNoDemandParameterTypes = new Type[] { typeof(IPrincipal), typeof(bool) };
                    MethodInfo setPrincipalNoDemandMethodInfo     = application.Context.GetType().GetMethod("SetPrincipalNoDemand", BindingFlags.Instance | BindingFlags.NonPublic, null, setPrincipalNoDemandParameterTypes, null);
                    setPrincipalNoDemandMethodInfo.Invoke(application.Context, setPrincipalNoDemandParameters);
                }
            }
            else
            {
                HttpWorkerRequest workerRequest =
                    (HttpWorkerRequest)application.Context.GetType().GetProperty("WorkerRequest", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true).Invoke(application.Context, null);

                string logonUser = workerRequest.GetServerVariable("LOGON_USER");
                string authType  = workerRequest.GetServerVariable("AUTH_TYPE");

                if (logonUser == null)
                {
                    logonUser = string.Empty;
                }
                if (authType == null)
                {
                    authType = string.Empty;
                }

                if (logonUser.Length == 0 && authType.Length == 0 || authType.ToLower() == "basic")
                {
                    identity = WindowsIdentity.GetAnonymous();
                }
                else
                {
                    identity = new WindowsIdentity(workerRequest.GetUserToken(), authType, System.Security.Principal.WindowsAccountType.Normal, true);
                }
            }

            if (identity != null)
            {
                WindowsPrincipal wp = new WindowsPrincipal(identity);

                object[]   setPrincipalNoDemandParameters     = new object[] { wp, false };
                Type[]     setPrincipalNoDemandParameterTypes = new Type[] { typeof(IPrincipal), typeof(bool) };
                MethodInfo setPrincipalNoDemandMethodInfo     = application.Context.GetType().GetMethod("SetPrincipalNoDemand", BindingFlags.Instance | BindingFlags.NonPublic, null, setPrincipalNoDemandParameterTypes, null);
                setPrincipalNoDemandMethodInfo.Invoke(application.Context, setPrincipalNoDemandParameters);
            }

            // return 401 if user is not authenticated:
            //  - application.Context.User might be null for ContentStore GetTreeNodeAllChildren?... request
            //  - currentPortalUser.Id might be startupuserid or visitoruserid if browser did not send 'negotiate' auth header yet
            //  - currentPortalUser might be null if application.Context.User.Identity is null or not an IUser
            IUser currentPortalUser = null;

            if (application.Context.User != null)
            {
                currentPortalUser = application.Context.User.Identity as IUser;
            }

            if ((application.Context.User == null) || (currentPortalUser != null &&
                                                       (currentPortalUser.Id == Identifiers.StartupUserId ||
                                                        currentPortalUser.Id == Identifiers.VisitorUserId)))
            {
                if (!IsLocalAxdRequest())
                {
                    AuthenticationHelper.DenyAccess(application);
                }
                return;
            }
        }
Esempio n. 3
0
        public override Stream Open()
        {
            if (_node == null)
            {
                try
                {
                    var allowCompiledContent = AllowCompiledContent(_repositoryPath);

                    // http://localhost/TestDoc.docx?action=RestoreVersion&version=2.0A
                    // When there are 'action' and 'version' parameters in the requested URL the portal is trying to load the desired version of the node of the requested action.
                    // This leads to an exception when the action doesn't have that version.
                    // _repositoryPath will point to the node of action and ContextNode will be the document
                    // if paths are not equal then we will return the last version of the requested action
                    if (PortalContext.Current == null || string.IsNullOrEmpty(PortalContext.Current.VersionRequest) || _repositoryPath != PortalContext.Current.ContextNodePath)
                    {
                        if (allowCompiledContent)
                        {
                            // elevated mode: pages, ascx files, etc.
                            using (new SystemAccount())
                            {
                                _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                            }
                        }
                        else
                        {
                            _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                        }
                    }
                    else
                    {
                        VersionNumber version;
                        if (VersionNumber.TryParse(PortalContext.Current.VersionRequest, out version))
                        {
                            Node node;

                            if (allowCompiledContent)
                            {
                                // elevated mode: pages, ascx files, etc.
                                using (new SystemAccount())
                                {
                                    node = Node.LoadNode(_repositoryPath, version);
                                }
                            }
                            else
                            {
                                node = Node.LoadNode(_repositoryPath, version);
                            }

                            if (node != null && node.SavingState == ContentSavingState.Finalized)
                            {
                                _node = node;
                            }
                        }
                    }

                    // we cannot serve the binary if the user has only See or Preview permissions for the content
                    if (_node != null && (_node.IsHeadOnly || _node.IsPreviewOnly) && HttpContext.Current != null)
                    {
                        AuthenticationHelper.ThrowForbidden(_node.Name);
                    }
                }
                catch (SenseNetSecurityException ex) //logged
                {
                    Logger.WriteException(ex);

                    if (HttpContext.Current == null || (_repositoryPath != null && _repositoryPath.ToLower().EndsWith(".ascx")))
                    {
                        throw;
                    }

                    AuthenticationHelper.DenyAccess(HttpContext.Current.ApplicationInstance);
                }
            }

            if (_node == null)
            {
                throw new ApplicationException(string.Format("{0} not found. RepositoryFile cannot be served.", _repositoryPath));
            }

            string propertyName = string.Empty;

            if (PortalContext.Current != null)
            {
                propertyName = PortalContext.Current.QueryStringNodePropertyName;
            }

            if (string.IsNullOrEmpty(propertyName))
            {
                propertyName = PortalContext.DefaultNodePropertyName;
            }

            var propType = _node.PropertyTypes[propertyName];

            if (propType == null)
            {
                throw new ApplicationException("Property not found: " + propertyName);
            }
            ////<only_for_test>
            //if(propType == null)
            //{
            //    StringBuilder sb = new StringBuilder();
            //    sb.AppendFormat("Property {0} not found.", propertyName);
            //    sb.AppendLine();
            //    foreach (var pt in _node.PropertyTypes)
            //    {
            //        sb.AppendFormat("PropertyName='{0}' - DataType='{1}'", pt.Name, pt.DataType);
            //        sb.AppendLine();
            //    }
            //    return new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
            //}
            ////</only_for_test>

            var    propertyDataType = propType.DataType;
            Stream stream;

            switch (propertyDataType)
            {
            case DataType.Binary:
                string         contentType;
                BinaryFileName fileName;
                stream = DocumentBinaryProvider.Current.GetStream(_node, propertyName, out contentType, out fileName);

                if (stream == null)
                {
                    throw new ApplicationException(string.Format("BinaryProperty.Value.GetStream() returned null. RepositoryPath={0}, OriginalUri={1}, AppDomainFriendlyName={2} ", this._repositoryPath, ((PortalContext.Current != null) ? PortalContext.Current.OriginalUri.ToString() : "PortalContext.Current is null"), AppDomain.CurrentDomain.FriendlyName));
                }

                //Set MIME type only if this is the main content (skip asp controls and pages,
                //page templates and other repository files opened during the request).
                //We need this in case of special images, fonts, etc, and handle the variable
                //at the end of the request (PortalContextModule.EndRequest method).
                if (HttpContext.Current != null &&
                    PortalContext.Current != null &&
                    PortalContext.Current.RepositoryPath == _repositoryPath &&
                    (string.IsNullOrEmpty(PortalContext.Current.ActionName) || PortalContext.Current.ActionName == "Browse") &&
                    !string.IsNullOrEmpty(contentType) &&
                    contentType != "text/asp")
                {
                    if (!HttpContext.Current.Items.Contains(RESPONSECONTENTTYPEKEY))
                    {
                        HttpContext.Current.Items.Add(RESPONSECONTENTTYPEKEY, contentType);
                    }

                    //set the value anyway as it may be useful in case of our custom file handler (SenseNetStaticFileHandler)
                    HttpContext.Current.Response.ContentType = contentType;

                    //add the necessary header for the css font-face rule
                    if (MimeTable.IsFontType(fileName.Extension))
                    {
                        HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Url.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped));
                    }
                }

                //set compressed encoding if necessary
                if (HttpContext.Current != null && MimeTable.IsCompressedType(fileName.Extension))
                {
                    HttpContext.Current.Response.Headers.Add("Content-Encoding", "gzip");
                }

                //let the client code log file downloads
                var file = _node as ContentRepository.File;
                if (file != null)
                {
                    ContentRepository.File.Downloaded(file.Id);
                }
                break;

            case DataType.String:
            case DataType.Text:
            case DataType.Int:
            case DataType.DateTime:
                stream = new MemoryStream(Encoding.UTF8.GetBytes(_node[propertyName].ToString()));
                break;

            default:
                throw new NotSupportedException(string.Format("The {0} property cannot be served because that's datatype is {1}.", propertyName, propertyDataType));
            }

            return(stream);
        }
        void OnAuthorizeRequest(object sender, EventArgs e)
        {
            PortalContext currentPortalContext = PortalContext.Current;
            var           d = NodeHead.Get("/Root");

            if (currentPortalContext != null && currentPortalContext.IsRequestedResourceExistInRepository)
            {
                var authMode = currentPortalContext.AuthenticationMode;
                //install time
                if (string.IsNullOrEmpty(authMode) && currentPortalContext.Site == null)
                {
                    authMode = "None";
                }

                if (string.IsNullOrEmpty(authMode))
                {
                    authMode = WebConfigurationManager.AppSettings["DefaultAuthenticationMode"];
                }

                bool appPerm = false;
                if (authMode == "Forms")
                {
                    appPerm = currentPortalContext.CurrentAction.CheckPermission();
                }
                else if (authMode == "Windows")
                {
                    currentPortalContext.CurrentAction.AssertPermissions();
                    appPerm = true;
                }
                else
                {
                    throw new NotSupportedException("None authentication is not supported");
                }

                var application     = sender as HttpApplication;
                var currentUser     = application.Context.User.Identity as User;
                var path            = currentPortalContext.RepositoryPath;
                var nodeHead        = NodeHead.Get(path);
                var isOwner         = nodeHead.CreatorId == currentUser.Id;
                var permissionValue = SecurityHandler.GetPermission(nodeHead, PermissionType.Open);

                if (permissionValue != PermissionValue.Allow || !appPerm)
                {
                    switch (authMode)
                    {
                    case "Forms":
                        if (User.Current.IsAuthenticated)
                        {
                            // user is authenticated, but has no permissions: return 403
                            application.Context.Response.StatusCode = 403;
                            application.Context.Response.Flush();
                            application.Context.Response.Close();
                        }
                        else
                        {
                            // user is not authenticated and visitor has no permissions: redirect to login page
                            // Get the login page Url (eg. http://localhost:1315/home/login)
                            string loginPageUrl = currentPortalContext.GetLoginPageUrl();
                            // Append trailing slash
                            if (loginPageUrl != null && !loginPageUrl.EndsWith("/"))
                            {
                                loginPageUrl = loginPageUrl + "/";
                            }

                            // Cut down the querystring (eg. drop ?Param1=value1@Param2=value2)
                            string currentRequestUrlWithoutQueryString = currentPortalContext.OriginalUri.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.Unescaped);

                            // Append trailing slash
                            if (!currentRequestUrlWithoutQueryString.EndsWith("/"))
                            {
                                currentRequestUrlWithoutQueryString = currentRequestUrlWithoutQueryString + "/";
                            }

                            // Redirect to the login page, if neccessary.
                            if (currentRequestUrlWithoutQueryString != loginPageUrl)
                            {
                                application.Context.Response.Redirect(loginPageUrl + "?OriginalUrl=" + System.Web.HttpUtility.UrlEncode(currentPortalContext.OriginalUri.ToString()), true);
                            }
                        }
                        break;

                    //case "Windows":
                    //    application.Context.Response.Clear();
                    //    application.Context.Response.Buffer = true;
                    //    application.Context.Response.Status = "401 Unauthorized";
                    //    application.Context.Response.AddHeader("WWW-Authenticate", "NTLM");
                    //    application.Context.Response.End();
                    //    break;
                    default:
                        AuthenticationHelper.DenyAccess(application);
                        break;
                    }
                }
            }
        }
Esempio n. 5
0
        public override Stream Open()
        {
            if (_node == null)
            {
                try
                {
                    // http://localhost/TestDoc.docx?action=RestoreVersion&version=2.0A
                    // When there are 'action' and 'version' parameters in the requested URL the portal is trying to load the desired version of the node of the requested action.
                    // This leads to an exception when the action doesn't have that version.
                    // _repositoryPath will point to the node of action and ContextNode will be the document
                    // if paths are not equal then we will return the last version of the requested action
                    if (PortalContext.Current == null || string.IsNullOrEmpty(PortalContext.Current.VersionRequest) || _repositoryPath != PortalContext.Current.ContextNodePath)
                    {
                        _node = Node.LoadNode(_repositoryPath);
                    }
                    else
                    {
                        VersionNumber version;
                        if (VersionNumber.TryParse(PortalContext.Current.VersionRequest, out version))
                        {
                            _node = Node.LoadNode(_repositoryPath, version);
                        }
                    }
                }
                catch (SenseNetSecurityException ex) //logged
                {
                    Logger.WriteException(ex);

                    if (HttpContext.Current == null)
                    {
                        throw;
                    }

                    AuthenticationHelper.DenyAccess(HttpContext.Current.ApplicationInstance);
                }
            }

            if (_node == null)
            {
                throw new ApplicationException(string.Format("{0} not found. RepositoryFile cannot be served.", _repositoryPath));
            }

            string propertyName = string.Empty;

            if (PortalContext.Current != null)
            {
                propertyName = PortalContext.Current.QueryStringNodePropertyName;
            }

            if (string.IsNullOrEmpty(propertyName))
            {
                propertyName = PortalContext.DefaultNodePropertyName;
            }

            var propType = _node.PropertyTypes[propertyName];

            if (propType == null)
            {
                throw new ApplicationException("Property not found: " + propertyName);
            }
            ////<only_for_test>
            //if(propType == null)
            //{
            //    StringBuilder sb = new StringBuilder();
            //    sb.AppendFormat("Property {0} not found.", propertyName);
            //    sb.AppendLine();
            //    foreach (var pt in _node.PropertyTypes)
            //    {
            //        sb.AppendFormat("PropertyName='{0}' - DataType='{1}'", pt.Name, pt.DataType);
            //        sb.AppendLine();
            //    }
            //    return new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
            //}
            ////</only_for_test>

            var    propertyDataType = propType.DataType;
            Stream stream;

            switch (propertyDataType)
            {
            case DataType.Binary:
                var bd = _node.GetBinary(propertyName);
                stream = bd.GetStream();
                if (stream == null)
                {
                    throw new ApplicationException(string.Format("BinaryProperty.Value.GetStream() returned null. RepositoryPath={0}, OriginalUri={1}, AppDomainFriendlyName={2} ", this._repositoryPath, ((PortalContext.Current != null) ? PortalContext.Current.OriginalUri.ToString() : "PortalContext.Current is null"), AppDomain.CurrentDomain.FriendlyName));
                }

                //let the client code log file downloads
                var file = _node as ContentRepository.File;
                if (file != null)
                {
                    ContentRepository.File.Downloaded(file.Id);
                }
                break;

            case DataType.String:
            case DataType.Text:
            case DataType.Int:
            case DataType.DateTime:
                stream = new MemoryStream(Encoding.UTF8.GetBytes(_node[propertyName].ToString()));
                break;

            default:
                throw new NotSupportedException(string.Format("The {0} property cannot be served because that's datatype is {1}.", propertyName, propertyDataType));
            }

            return(stream);
        }
Esempio n. 6
0
        public override Stream Open()
        {
            if (_node == null)
            {
                try
                {
                    var allowCompiledContent = AllowCompiledContent(_repositoryPath);

                    // http://localhost/TestDoc.docx?action=RestoreVersion&version=2.0A
                    // When there are 'action' and 'version' parameters in the requested URL the portal is trying to load the desired version of the node of the requested action.
                    // This leads to an exception when the action doesn't have that version.
                    // _repositoryPath will point to the node of action and ContextNode will be the document
                    // if paths are not equal then we will return the last version of the requested action.
                    // We also have to ignore the version request parameter in case of binary handler, because that
                    // ashx must not have multiple versions.
                    if (PortalContext.Current == null || PortalContext.Current.BinaryHandlerRequestedNodeHead != null || string.IsNullOrEmpty(PortalContext.Current.VersionRequest) || _repositoryPath != PortalContext.Current.ContextNodePath)
                    {
                        if (allowCompiledContent)
                        {
                            // elevated mode: pages, ascx files, etc.
                            using (new SystemAccount())
                            {
                                _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                            }
                        }
                        else
                        {
                            _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                        }
                    }
                    else
                    {
                        VersionNumber version;
                        if (VersionNumber.TryParse(PortalContext.Current.VersionRequest, out version))
                        {
                            Node node;

                            if (allowCompiledContent)
                            {
                                // elevated mode: pages, ascx files, etc.
                                using (new SystemAccount())
                                {
                                    node = Node.LoadNode(_repositoryPath, version);
                                }
                            }
                            else
                            {
                                node = Node.LoadNode(_repositoryPath, version);
                            }

                            if (node != null && node.SavingState == ContentSavingState.Finalized)
                            {
                                _node = node;
                            }
                        }
                    }

                    // we cannot serve the binary if the user has only See or Preview permissions for the content
                    if (_node != null && (_node.IsHeadOnly || _node.IsPreviewOnly) && HttpContext.Current != null)
                    {
                        AuthenticationHelper.ThrowForbidden(_node.Name);
                    }
                }
                catch (SenseNetSecurityException ex) // logged
                {
                    SnLog.WriteException(ex);

                    if (HttpContext.Current == null || (_repositoryPath != null && _repositoryPath.ToLower().EndsWith(".ascx")))
                    {
                        throw;
                    }

                    AuthenticationHelper.DenyAccess(HttpContext.Current.ApplicationInstance);
                }
            }

            if (_node == null)
            {
                throw new ApplicationException(string.Format("{0} not found. RepositoryFile cannot be served.", _repositoryPath));
            }

            string propertyName = string.Empty;

            if (PortalContext.Current != null)
            {
                propertyName = PortalContext.Current.QueryStringNodePropertyName;
            }

            if (string.IsNullOrEmpty(propertyName))
            {
                propertyName = PortalContext.DefaultNodePropertyName;
            }

            var propType = _node.PropertyTypes[propertyName];

            if (propType == null)
            {
                throw new ApplicationException("Property not found: " + propertyName);
            }

            var    propertyDataType = propType.DataType;
            Stream stream;

            switch (propertyDataType)
            {
            case DataType.Binary:
                string         contentType;
                BinaryFileName fileName;

                // Images need to be handled differently, because of these reasons:
                // - dimensions may be changed dynamically, based on request parameters
                // - preview images may be restricted (redacted) based on permissions
                if (_node is Image img)
                {
                    var parameters = HttpContext.Current?.Request.QueryString;

                    stream = img.GetImageStream(propertyName,
                                                parameters?.AllKeys.ToDictionary(k => k ?? string.Empty, k => (object)parameters[k]),
                                                out contentType,
                                                out fileName);
                }
                else
                {
                    stream = DocumentBinaryProvider.Current.GetStream(_node, propertyName, out contentType, out fileName);
                }

                if (stream == null)
                {
                    throw new ApplicationException(string.Format("BinaryProperty.Value.GetStream() returned null. RepositoryPath={0}, OriginalUri={1}, AppDomainFriendlyName={2} ", this._repositoryPath, ((PortalContext.Current != null) ? PortalContext.Current.RequestedUri.ToString() : "PortalContext.Current is null"), AppDomain.CurrentDomain.FriendlyName));
                }

                // Set MIME type only if this is the main content (skip asp controls and pages,
                // page templates and other repository files opened during the request).
                // We need this in case of special images, fonts, etc, and handle the variable
                // at the end of the request (PortalContextModule.EndRequest method).
                if (HttpContext.Current != null &&
                    PortalContext.Current != null &&
                    string.Equals(PortalContext.Current.RepositoryPath, _repositoryPath, StringComparison.InvariantCultureIgnoreCase) &&
                    (string.IsNullOrEmpty(PortalContext.Current.ActionName) || string.Equals(PortalContext.Current.ActionName, "Browse", StringComparison.InvariantCultureIgnoreCase)) &&
                    !string.IsNullOrEmpty(contentType) &&
                    contentType != "text/asp")
                {
                    if (!HttpContext.Current.Items.Contains(RESPONSECONTENTTYPEKEY))
                    {
                        HttpContext.Current.Items.Add(RESPONSECONTENTTYPEKEY, contentType);
                    }

                    // set the value anyway as it may be useful in case of our custom file handler (SenseNetStaticFileHandler)
                    HttpContext.Current.Response.ContentType = contentType;

                    // add the necessary header for the css font-face rule
                    if (MimeTable.IsFontType(fileName.Extension))
                    {
                        HttpHeaderTools.SetAccessControlHeaders();
                    }
                }

                // set compressed encoding if necessary
                if (HttpContext.Current != null && MimeTable.IsCompressedType(fileName.Extension))
                {
                    HttpContext.Current.Response.Headers.Add("Content-Encoding", "gzip");
                }

                // let the client code log file downloads
                var file = _node as ContentRepository.File;
                if (file != null)
                {
                    ContentRepository.File.Downloaded(file.Id);
                }
                break;

            case DataType.String:
            case DataType.Text:
            case DataType.Int:
            case DataType.DateTime:
                stream = new MemoryStream(Encoding.UTF8.GetBytes(_node[propertyName].ToString()));
                break;

            default:
                throw new NotSupportedException(string.Format("The {0} property cannot be served because that's datatype is {1}.", propertyName, propertyDataType));
            }

            return(stream);
        }