Authenticating Website Members as Users in CKFinder v3

Before starting this question, I must indicate that my knowledge of ASP.NET and C # is pretty much zero.

I am trying to integrate a version of CKFinder v3 in ASP.NET into a site created in a different language, and everything is going well so far; Everything is set up for me the way I want, and it works when I provide unlimited access to CKF, but I'm stuck now in trying to restrict access to it by authenticating only some members of my site to use it. All pages that appear CKFinder on my site are accessible only by some members, but I need an additional level of security if, for example, someone finds out a direct path to my file "ckfinder.html".

In the ASP version of CKFinder, I simply added this line to a function that checks my member privileges, where isEditor was a Boolean value that was assigned to each member based on information from my database:

 session("accessckf")=isEditor 

and then edited the CheckAuthentication() function in the CKFinder "config.asp" file to read:

 function CheckAuthentication() CheckAuthentication=session("accessckf") end function 

Reading through this “Howto,” authentication seems a lot more complicated in v3, but after a lot of trial and error and some help from Lesiman , I created this C # file, which is in my CKF directory:

 <%@page codepage="65001" debug="true" language="c#" lcid="6153"%> <%@import namespace="CKSource.CKFinder.Connector.Core"%> <%@import namespace="CKSource.CKFinder.Connector.Core.Authentication"%> <%@import namespace="CKSource.CKFinder.Connector.Core.Builders"%> <%@import namespace="CKSource.CKFinder.Connector.Host.Owin"%> <%@import namespace="Owin"%> <%@import namespace="System.Data.Odbc"%> <%@import namespace="System.Threading"%> <%@import namespace="System.Threading.Tasks"%> <script runat="server"> public void Configuration(IAppBuilder appBuilder){ var connectorBuilder=ConfigureConnector(); var connector=connectorBuilder.Build(new OwinConnectorFactory()); appBuilder.Map("/path/to/connector",builder=>builder.UseConnector(connector)); } public ConnectorBuilder ConfigureConnector(){ var connectorBuilder=new ConnectorBuilder(); connectorBuilder.SetAuthenticator(new MyAuthenticator()); return connectorBuilder; } public class MyAuthenticator:IAuthenticator{ public Task<IUser> AuthenticateAsync(ICommandRequest commandRequest,CancellationToken cancellationToken){ var domain=HttpContext.Current.Request.Url.Host; var cookie=HttpContext.Current.Request.Cookies[urlDomain]; var password=""; var username=""; var user=new User(false,null); if (cookie!=null){ if (cookie["username"]!=null) username=cookie["username"]; if (cookie["password"]!=null) password=cookie["password"]; if(username!=""&&password!=""){ var connection=new OdbcConnection("database=[database];driver=MySQL;pwd=[pwd];server=[server];uid=[uid];"); connection.Open(); OdbcDataReader records=new OdbcCommand("SELECT ISEDITOR FROM MEMBERS WHERE USERNAME='"+username+"' AND PASSWORD='"+password+"'",connection).ExecuteReader(); if(records.HasRows){ records.Read(); bool isEditor=records.GetString(0)=="1"; var roles="member"; if(isEditor) roles="editor,member"; user=new User(isEditor,roles.Split(',')); } records.Close(); connection.Close(); } } return Task.FromResult((IUser)user); } } </script> 

Loading this page does not lead to errors (which does not necessarily mean that it works as an attempt to write something to the screen from the public class , for some reason it does not work), so now I'm at the stage of somehow checking the file’s authenticity .

I initially tried to download it via XMLHttp from my function, which checks the membership rights for the site, but, as I suspected, and how Lesmian confirmed that it would not work. After more trial and error, I added code to check the privileges of the site members on the C # file, which brings me to where I am now: stuck!

What do I need to change in CKFinder to use this user file for user authentication?

+5
source share
2 answers

First you need a connector between the ASP session and the CKFinder.Net authenticator. Here is an example that serializes the contents of an ASP session to JSON.

Put connector.asp in a public place. http://myaspwebsite.com/connector.asp e.g.

connector.asp

 <%@Language=VBScript CodePage=65001%> <% Option Explicit %> <!--#include file="JSON.asp"--> <% ' obtain JSON.asp from https://github.com/tugrul/aspjson/archive/master.zip ' just for testing, must be removed in the production environment Session("isEditor") = True Session("isMember") = True ' only local requests allowed ' instead of local and remote ip comparison, a secret key can be used If Request.ServerVariables("LOCAL_ADDR") <> Request.ServerVariables("REMOTE_ADDR") Then Response.Status = "403 Forbidden" Response.End End If Response.ContentType = "application/json" Response.Charset = "utf-8" Dim JSONObject, Key Set JSONObject = jsObject() For Each Key In Session.Contents If Not IsObject(Session.Contents(Key)) Then 'skip the objects cannot be serialized JSONObject(Key) = Session.Contents(Key) End If Next JSONObject.Flush %> 

CKFinder 3.3.0 comes with a standard connector, which can be found in /ckfinder/bin/CKSource.CKFinder.Connector.WebApp.dll , remove it .

Examine the following program and be sure to replace builder.Map("/connector", SetupConnector); and new Uri("http://myaspwebsite.com/connector.asp"); your own meanings.

It simply authenticates users by validating ASP Session isEditor and isMember via connector.asp and finally asserts the roles of editor , member or none.

I assume that you configured the editor and member roles in web.config .

Then put Shaggy.cs in /ckfinder/App_Code . Create the App_Code directory if it does not exist..Net files in this folder will be compiled on the fly.

See Shared Code Folders in ASP.NET Web Projects for more information.

Shaggy.cs

 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Newtonsoft.Json.Linq; using Owin; [assembly: Microsoft.Owin.OwinStartup(typeof(CKSource.CKFinder.Connector.Shaggy.Startup))] namespace CKSource.CKFinder.Connector.Shaggy { using FileSystem.Local; using FileSystem.Dropbox; using Core; using Core.Authentication; using Config; using Core.Builders; using Core.Logs; using Host.Owin; using Logs.NLog; using KeyValue.EntityFramework; public class Startup { public void Configuration(IAppBuilder builder) { LoggerManager.LoggerAdapterFactory = new NLogLoggerAdapterFactory(); RegisterFileSystems(); builder.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "ApplicationCookie", AuthenticationMode = AuthenticationMode.Active }); //replace connector path with yours builder.Map("/connector", SetupConnector); } private static void RegisterFileSystems() { FileSystemFactory.RegisterFileSystem<LocalStorage>(); FileSystemFactory.RegisterFileSystem<DropboxStorage>(); } private static void SetupConnector(IAppBuilder builder) { var keyValueStoreProvider = new EntityFrameworkKeyValueStoreProvider("CacheConnectionString"); var authenticator = new ShaggysAuthenticator(); var connectorFactory = new OwinConnectorFactory(); var connectorBuilder = new ConnectorBuilder(); var connector = connectorBuilder .LoadConfig() .SetAuthenticator(authenticator) .SetRequestConfiguration( (request, config) => { config.LoadConfig(); config.SetKeyValueStoreProvider(keyValueStoreProvider); }) .Build(connectorFactory); builder.UseConnector(connector); } } public class ShaggysAuthenticator : IAuthenticator { // this method makes an http request on the background to gather ASP all session contents and returns a JSON object // if the request contains ASP session cookie(s) private static JObject GetAspSessionState(ICommandRequest requestContext) { // building Cookie header with ASP session cookies var aspSessionCookies = string.Join(";", requestContext.Cookies.Where(cookie => cookie.Key.StartsWith("ASPSESSIONID")) .Select(cookie => string.Join("=", cookie.Key, cookie.Value))); if (aspSessionCookies.Length == 0) { // logs can be found in /ckfinder/App_Data/logs LoggerManager.GetLoggerForCurrentClass().Info("No ASP session cookie found"); // don't make an extra request to the connector.asp, there no session initiated return new JObject(); } //replace this URL with your connector.asp's var publicAspSessionConnectorUrl = new Uri("http://myaspwebsite.com/connector.asp"); var localSafeAspSessionConnectorUrl = new UriBuilder(publicAspSessionConnectorUrl) { Host = requestContext.LocalIpAddress }; using (var wCli = new WebClient()) try { wCli.Headers.Add(HttpRequestHeader.Cookie, aspSessionCookies); wCli.Headers.Add(HttpRequestHeader.Host, publicAspSessionConnectorUrl.Host); return JObject.Parse(wCli.DownloadString(localSafeAspSessionConnectorUrl.Uri)); } catch (Exception ex) // returning an empty JObject object in any fault { // logs can be found in /ckfinder/App_Data/logs LoggerManager.GetLoggerForCurrentClass().Error(ex); return new JObject(); } } public Task<IUser> AuthenticateAsync(ICommandRequest commandRequest, CancellationToken cancellationToken) { var aspSessionState = GetAspSessionState(commandRequest); var roles = new List<string>(); var isEditor = aspSessionState.GetNullSafeValue("isEditor", false); var isMember = aspSessionState.GetNullSafeValue("isMember", false); if (isEditor) roles.Add("editor"); if (isMember) roles.Add("member"); var isAuthenticated = isEditor || isMember; var user = new User(isAuthenticated, roles); return Task.FromResult((IUser)user); } } public static class JObjectExtensions { // an extension method to help case insensitive lookups with a default value to get avoid NullReferenceException public static T GetNullSafeValue<T>(this JObject jobj, string key, T defaultValue = default(T)) { dynamic val = jobj.GetValue(key, StringComparison.OrdinalIgnoreCase); if (val == null) return defaultValue; return (T)val; } } } 

You should now have a working CKFinder connector. Change the logic in the AuthenticateAsync method if you need to, and see how CKFinder handles the management of classic ASP.

+3
source

Have you installed your own authentication provider with ConnectorBuilder?

 public ConnectorBuilder ConfigureConnector() { var connectorBuilder = new ConnectorBuilder(); connectorBuilder.SetAuthenticator(new MyAuthenticator()); return connectorBuilder; } 

Here you can find the full example: http://docs.cksource.com/ckfinder3-net/configuration_by_code.html .

UPDATE

In addition, you must register the ConnectorBuilder inside the Startup class to add it for the pipeline request:

 public void Configuration(IAppBuilder appBuilder) { var connectorBuilder = ConfigureConnector(); var connector = connectorBuilder.Build(new OwinConnectorFactory()); appBuilder.Map("/CKFinder/connector", builder => builder.UseConnector(connector)); } 

All this from the link to the documentation that I provided earlier.

+2
source

All Articles