public static DenyAccess ( System.Web.HttpApplication application ) : void | ||
application | System.Web.HttpApplication | |
return | void |
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; } } } }
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; } }
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; } } } }
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); }
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); }