CKFinder 3 – ASP.NET Connector Documentation
Integration

Embedding CKFinder on a Website

Once you are able to run CKFinder samples it is time to connect CKFinder with your application. Please refer to the Quick Start Guide to read more about integrating CKFinder with your website (e.g. displaying it embedded on a page, in a popup etc.).

Integration with CKEditor 5

The integration between CKEditor 5 and CKFinder is based on a dedicated plugin, which is by default included and enabled in all CKEditor 5 Builds.

For detailed information about the integration between CKEditor 5 and CKFinder, please refer to the CKFinder file manager integration article in the CKEditor 5 documentation. See also the working demo on the CKFinder Samples site.

Quick Example

The code example below presents the full integration mode.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CKEditor 5 Integration Example</title>
</head>
<body>
<div id="editor"></div>
<script src="https://cdn.ckeditor.com/ckeditor5/11.2.0/classic/ckeditor.js"></script>
<script src="/ckfinder/ckfinder.js"></script>
<script type="text/javascript">
ClassicEditor
.create( document.querySelector( '#editor' ), {
ckfinder: {
uploadUrl: '/ckfinder/connector?command=QuickUpload&type=Files&responseType=json'
},
toolbar: [ 'ckfinder', 'imageUpload', '|', 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo' ]
} )
.catch( function( error ) {
console.error( error );
} );
</script>
</body>
</html>

Integration with CKEditor 4

CKFinder can be easily integrated with CKEditor 4. Refer to the CKEditor 4 Integration article for a more detailed documentation. See also the working demo on the CKFinder site.

CKFinder.setupCKEditor()

The simplest way to integrate CKFinder with CKEditor 4 is the CKFinder.setupCKEditor method. This method takes a CKEditor 4 instance which will be set up as the first argument (editor).

If no argument is passed or the editor argument is null, CKFinder will integrate with all CKEditor 4 instances.

Example 1

Integrate with a specific CKEditor 4 instance:

var editor = CKEDITOR.replace( 'editor1' );
CKFinder.setupCKEditor( editor );

Example 2

Integrate with all existing and future CKEditor 4 instances:

CKFinder.setupCKEditor();
CKEDITOR.replace( 'editor1' );

Manual Integration

In order to manually configure CKEditor 4 to use CKFinder, you will need to pass some additional CKFinder configuration settings to the CKEditor 4 instance. This method, although slightly more complex, gives you more flexibility.

Refer to the CKEditor 4 documentation for a detailed explanation of particular configuration settings that you can use.

Important Information

The filebrowser*BrowseUrl paths have to point to the location of ckfinder.html, which in case of installation from NuGet packages is by default located in /ckfinder/CKFinderScripts/ckfinder.html.

The filebrowser*UploadUrl paths in CKFinder 2.x and CKFinder 3.x are different.

The filebrowserUploadUrl and filebrowserImageUploadUrl paths point to the connector's route. These paths are virtual and do not exist on the disk.

Example 1

The sample below shows the configuration code that can be used to insert a CKEditor 4 instance with CKFinder integrated. The browse and upload paths for images are configured separately from CKFinder default paths.

CKEDITOR.replace( 'editor1',
{
filebrowserBrowseUrl: '/ckfinder/ckfinder.html',
filebrowserImageBrowseUrl: '/ckfinder/ckfinder.html?type=Images',
filebrowserUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Files',
filebrowserImageUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Images'
});

Remember to change the /ckfinder/connector path in the above URLs if you installed CKFinder in a different location or mapped the CKFinder connector to a different route.

Example 2

Specifying destination folder for uploads made directly in the Upload tab (1) in CKEditor 4:

CKEditor Image Dialog Window

When configuring CKEditor 4 filebrowserUploadUrl settings, it is possible to point CKFinder to a subfolder for a given resource type and upload files directly to this subfolder. In order to do this, add the currentFolder attribute to the query string for *UploadUrl settings:

CKEDITOR.replace( 'editor1',
{
filebrowserBrowseUrl: '/ckfinder/ckfinder.html',
filebrowserImageBrowseUrl: '/ckfinder/ckfinder.html?type=Images',
filebrowserUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Files&currentFolder=/archive/',
filebrowserImageUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Images&currentFolder=/cars/'
});

Note: The folder specified must already exist on the server (see archive and cars in the example above).

Integrating in Existing Application

This section describes how to integrate the CKFinder connector in an existing ASP.NET application. For the purpose of this article, a newly created project based on an MVC ASP.NET template will be used as a sample application.

Creating an MVC ASP.NET Project from a Template

To create a new MVC ASP.NET project in Visual Studio 2015, proceed as follows:

  1. Open Visual Studio and navigate to File > New > Project.

    Creating a new project in Visual Studio

     

  2. In the New Project dialog choose ASP.NET Web Application and accept with OK.

    Creating a new ASP.NET web application in Visual Studio

     

  3. In the project templates dialog choose the MVC template from the ASP.NET 4 template list and click OK.

    Choosing the MVC template in Visual Studio

     

After performing the steps described above, Visual Studio will generate files for the project. You can check if the application is compiling and running correctly by starting a debugging session (Debug > Start Debugging).

With an application to base on ready, you can proceed to CKFinder integration.

Integrating CKFinder

The integration of CKFinder in an existing application can be done in two ways:

  • Using CKFinder NuGet Packages, which is is the preferred way that makes the entire process much easier and shorter. Defining application dependencies in this way will allow for easy updates of CKFinder in the future.
  • Using files provided in the CKFinder ZIP distribution package, which is a bit cumbersome, but may be the preferred way of integration in some legacy projects.

Integration Using CKFinder NuGet Packages

The following section describes how to integrate an existing application with CKFinder using NuGet packages.

Installing Required NuGet Packages

To add CKFinder to your example application you will have to search the NuGet repository for required packages. To do that, open the NuGet package manager in the Visual Studio menu: Project > Manage NuGet Packages....

Using NuGet Package Manager in Visual Studio

 

In the package manager, search the NuGet repository for the following packages, and install them:

The packages above are core libraries required to set up and run the ASP.NET connector. While they are enough to start using the connector, it is highly recommended to install two additional packages:

The last package that may prove useful is static configuration through XML:

After the required packages are installed, it is time to add required changes in the application code.

Configuring the Logger

Since CKSource.CKFinder.Connector.Logs.NLog was installed to simplify debugging, prepare the logging environment to see detailed error messages in case something goes wrong.

The NLog logger used by the CKFinder connector looks for its configuration file (NLog.config) in the base directory of the application (the directory where the Web.config file is placed). Create an NLog configuration file (NLog.config) with the following content:

<nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets async="true">
<target xsi:type="File" name="logFile" fileName="${basedir}/App_Data/logs/ckfinder.log"
archiveFileName="${basedir}/App_Data/logs/archives/ckfinder.{#}.log" archiveEvery="Day" archiveNumbering="Rolling" maxArchiveFiles="5" concurrentWrites="true" keepFileOpen="false"
layout="${level} | ${logger} | ${longdate} | ${message}${onexception: | ${exception:format=ToString,StackTrace:maxInnerExceptionLevel=10}}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>

The created NLog.config file defines the directory where log files will be created, and enables logging of stack traces for exceptions. In the configuration file presented above, logs are defined to be saved and archived in the App_Data/logs/ directory placed in the application base directory (represented in NLog configuration as the ${basedir} placeholder).

To find out more about possibilities and configuration options of NLog please refer to the official Nlog tutorial.

Creating a Custom Authenticator

To restrict access to the CKFinder connector only for authenticated users you need to create a custom authenticator (see Implementing Authenticator). To add a custom authenticator, create a new class with following content in your project:

using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
namespace MVCIntegrationExample
{
public class CustomCKFinderAuthenticator : IAuthenticator
{
public Task<IUser> AuthenticateAsync(ICommandRequest commandRequest, CancellationToken cancellationToken)
{
var claimsPrincipal = commandRequest.Principal as ClaimsPrincipal;
var roles = claimsPrincipal?.Claims?.Where(x => x.Type == ClaimTypes.Role).Select(x => x.Value).ToArray();
/*
* Enable CKFinder only for authenticated users.
*/
var isAuthenticated = claimsPrincipal.Identity.IsAuthenticated;
var user = new User(isAuthenticated, roles);
return Task.FromResult((IUser)user);
}
}
}

Modifying the Application Code

CKFinder requires Owin to run. This means that for an application that uses only global.asax you will have to install the Microsoft.Owin.Host.SystemWeb package.

Have a look at the Startup.cs file in the project you created. It contains the following application bootstrap code at the beginning:

using Microsoft.Owin;
using Owin;
[assembly: OwinStartupAttribute(typeof(MVCIntegrationExample.Startup))]
namespace MVCIntegrationExample
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
}
}

After modifications required to set up the connector, the Startup.cs file contains the following code:

using Microsoft.Owin;
using Owin;
[assembly: OwinStartupAttribute(typeof(MVCIntegrationExample.Startup))]
namespace MVCIntegrationExample
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
/*
* If you installed CKSource.CKFinder.Connector.Logs.NLog you can start the logger:
* LoggerManager.LoggerAdapterFactory = new NLogLoggerAdapterFactory();
* Keep in mind that the logger should be initialized only once and before any other
* CKFinder method is invoked.
*/
/*
* Register the "local" type backend file system.
*/
FileSystemFactory.RegisterFileSystem<LocalStorage>();
/*
* Map the CKFinder connector service under a given path. By default the CKFinder JavaScript
* client expects the ASP.NET connector to be accessible under the "/ckfinder/connector" route.
*/
app.Map("/ckfinder/connector", SetupConnector);
}
private static void SetupConnector(IAppBuilder app)
{
/*
* Create a connector instance using ConnectorBuilder. The call to the LoadConfig() method
* will configure the connector using CKFinder configuration options defined in Web.config.
*/
var connectorFactory = new OwinConnectorFactory();
var connectorBuilder = new ConnectorBuilder();
/*
* Create an instance of authenticator implemented in the previous step.
*/
var customAuthenticator = new CustomCKFinderAuthenticator();
connectorBuilder
/*
* Provide the global configuration.
*
* If you installed CKSource.CKFinder.Connector.Config, you should load the static configuration
* from XML:
* connectorBuilder.LoadConfig();
*/
.LoadConfig()
.SetAuthenticator(customAuthenticator)
.SetRequestConfiguration(
(request, config) =>
{
/*
* If you installed CKSource.CKFinder.Connector.Config, you might want to load the static
* configuration from XML as a base configuration to modify:
*/
config.LoadConfig();
/*
* Configure settings per request.
*
* The minimal configuration has to include at least one backend, one resource type
* and one ACL rule.
*
* For example:
*/
config.AddBackend("default", new LocalStorage(@"C:\files"));
config.AddResourceType("images", builder => builder.SetBackend("default", "images"));
config.AddAclRule(new AclRule(
new StringMatcher("*"),
new StringMatcher("*"),
new StringMatcher("*"),
new Dictionary<Permission, PermissionType> { { Permission.All, PermissionType.Allow } }));
/*
* If you installed CKSource.CKFinder.Connector.KeyValue.FileSystem, you may enable caching:
*/
var defaultBackend = config.GetBackend("default");
var keyValueStoreProvider = new FileSystemKeyValueStoreProvider(defaultBackend);
config.SetKeyValueStoreProvider(keyValueStoreProvider);
}
);
/*
* Build the connector middleware.
*/
var connector = connectorBuilder
.Build(connectorFactory);
/*
* Add the CKFinder connector middleware to the web application pipeline.
*/
app.UseConnector(connector);
}
}
}

If you want to mix multiple owin middlewares see Mixing Multiple Owin Middlewares

You may find documentation for the global settings here, and the per request configuration options are documented here.

If you installed CKSource.CKFinder.Connector.Config and you want to use the static configuration in the Web.config file, before you start the application and check if the connector works, there are a few additional steps required. The configuration of the connector is defined in the Web.config file under the <ckfinder /> tag. You can find the description of the supported configuration options in the Configuration section.

By default CKFinder configuration defines the default backend (which is of local type that you registered). As you may see, the root configuration option of this backend tells the backend that files uploaded by users should be saved to the userfiles folder, so you need to create it in the base directory of the application.

At this point the CKFinder connector is ready, so you can start the application and give it a try. As you configured the connector to be accessible only for authenticated users, you will have to register the user and log in first — otherwise you will get redirected to the Log in page. After you are logged in, navigate to /ckfinder/connector?command=Init where you should see the JSON response of the Init command, which means that the connector runs properly. If you see any error, refer to the Debugging and Logging section.

With the connector up and running, create a sample page where you can see CKFinder in action. To simplyfy this step, modify the existing HomeController (/Controllers/HomeController.cs) created by the MVC application template. You need to add a page accessible only to authenticated users where they can use CKFinder. The code below presents the modified controller with authorization options added, and an action used for the page with CKFinder:

The /Controllers/HomeController.cs file:

namespace MVCIntegrationExample.Controllers
{
[Authorize]
public class HomeController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
[AllowAnonymous]
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
[AllowAnonymous]
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
public ActionResult CKFinder()
{
ViewBag.Message = "Welcome to CKFinder!";
return View();
}
}
}

You also need to create a view for the new action you added:

The /Views/Home/CKFinder.cshtml file:

<h2>CKFinder widget usage example</h2>
<h3>@ViewBag.Message</h3>
<div id="ckfinder-widget"></div>
<script src="@Url.Content("~/CKFinderScripts/ckfinder.js")" type="text/javascript"></script>
<script>
CKFinder.widget( 'ckfinder-widget', {
width: '100%',
height: 700
} );
</script>

The last thing you need is a link to the CKFinder page in the application navigation bar. To add it, modify the /Views/Shared/_Layout.chtml file in the following way:

The /Views/Shared/_Layout.chtml file:

...
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
<li>@Html.ActionLink("CKFinder", "CKFinder", "Home")</li>
</ul>
...

Done! After logging in to the application and navigating to the CKFinder page you will see a working example of a CKFinder widget.

CKFinder widget usage example page