我已经基于https://blogs.msdn.microsoft.com/robert_mcmurray/2011/06/30/how-to-create-an-authentication-provider-for-ftp-7-5-using-blogengine-nets-xml-membership-files/实现了针对ftp网站的curom身份验证,但IFtpHomeDirectoryProvider.GetUserHomeDirectoryData
没有上升
public class FtpEngineNetAuthentication : BaseProvider,
IFtpAuthenticationProvider
, IFtpRoleProvider
, IFtpHomeDirectoryProvider
, IFtpPostprocessProvider
, IFtpLogProvider
{
private readonly string _logfile = Path.Combine(@"c:\test", "logs", "FtpExtension.log");
private string _dbConnectionString;
private string _ftpHomeDirectory;
protected override void Initialize(StringDictionary config)
{
// Retrieve the paths from the configuration dictionary.
_dbConnectionString = config["RextorConnectionString"];
_ftpHomeDirectory = config["ftpHomeDirectory"];
}
bool TryGetUser(string login, out User user)
{
user = null;
try
{
using (var conn = new SqlConnection(_dbConnectionString))
{
var command = new SqlCommand("SELECT UserName, Password, HashAlgorithm, PasswordSalt FROM Orchard_Users_UserPartRecord WHERE UserName = @login", conn);
command.Parameters.AddWithValue("@login", login);
conn.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read()) // Don't assume we have any rows.
{
user = new User()
{
Login = reader.GetString(0),
Password = reader.GetString(1),
HashAlgorithm = reader.GetString(2),
PasswordSalt = reader.GetString(3)
};
}
}
conn.Close();
}
}
catch (Exception)
{
return false;
}
return true;
}
// Define the GetUserHomeDirectoryData method.
string IFtpHomeDirectoryProvider.GetUserHomeDirectoryData(string sessionId, string siteName, string userName)
{
// Test if the path to the home directory is empty.
if (string.IsNullOrEmpty(_ftpHomeDirectory))
{
// Throw an exception if the path is missing or empty.
throw new ArgumentException(@"Missing ftpHomeDirectory value in configuration.");
}
LogMessage($"directory: {userName}");
var result = $@"{_ftpHomeDirectory}\{userName}";
LogMessage(result);
// Return the path to the home directory.
return result;
}
// Define the AuthenticateUser method.
bool IFtpAuthenticationProvider.AuthenticateUser(string sessionId, string siteName, string userName, string userPassword, out string canonicalUserName)
{
// Define the canonical user name.
canonicalUserName = userName.Replace("@", "").Replace(".", "");
// Validate that the user name and password are not empty.
if (String.IsNullOrEmpty(userName) || String.IsNullOrEmpty(userPassword))
{
// Return false (authentication failed) if either are empty.
return false;
}
try
{
// Create a user object.
User user = null;
// Test if the user name is in the dictionary of users.
if (TryGetUser(userName, out user))
{
var saltBytes = Convert.FromBase64String(user.PasswordSalt);
// Retrieve a sequence of bytes for the password.
bool isValid;
if (user.HashAlgorithm == "PBKDF2")
{
LogMessage($"user password: {user.Password}");
LogMessage($"user salt: {user.PasswordSalt}");
LogMessage($"user salt&pwd: {Encoding.Unicode.GetString(CombineSaltAndPassword(saltBytes, userPassword))}");
// We can't reuse ComputeHashBase64 as the internally generated salt repeated calls to Crypto.HashPassword() return different results.
isValid = true;
//Crypto.VerifyHashedPassword(user.Password, Encoding.Unicode.GetString(CombineSaltAndPassword(saltBytes, userPassword)));
//PasswordHash.ValidatePassword(user.Password, Encoding.Unicode.GetString(CombineSaltAndPassword(saltBytes, userPassword)));
//BCryptHelper.CheckPassword(user.Password, Encoding.Unicode.GetString(CombineSaltAndPassword(saltBytes, userPassword)));
}
else
{
isValid = SecureStringEquality(user.Password, ComputeHashBase64(user.HashAlgorithm, saltBytes, userPassword));
}
//if (isValid && user.HashAlgorithm != DefaultHashAlgorithm)
//{
// var keepOldConfiguration = _appConfigurationAccessor.GetConfiguration("Orchard.Users.KeepOldPasswordHash");
// if (String.IsNullOrEmpty(keepOldConfiguration) || keepOldConfiguration.Equals("false", StringComparison.OrdinalIgnoreCase))
// {
// user.HashAlgorithm = DefaultHashAlgorithm;
// user.Password = ComputeHashBase64(user.HashAlgorithm, saltBytes, userPassword);
// }
//}
return isValid;
}
}
catch (Exception ex)
{
LogMessage(ex.Message);
// Raise an exception if an error occurs.
throw new ProviderException(ex.Message, ex.InnerException);
}
// Return false (authentication failed) if authentication fails to this point.
return false;
}
bool IFtpRoleProvider.IsUserInRole(string sessionId, string siteName,string userName, string userRole)
{
LogMessage($"check role: {userName} - {userRole}");
return true;
}
public FtpProcessStatus HandlePostprocess(FtpPostprocessParameters postProcessParameters)
{
LogMessage("Running Post Process"); //this message never appears
return FtpProcessStatus.FtpProcessContinue;
}
public void Log(FtpLogEntry logEntry)
{
//LogMessage(logEntry.);
}
private void LogMessage(string logEntry)
{
using (var sw = new StreamWriter(_logfile, true))
{
// Retrieve the current date and time for the log entry.
var dt = DateTime.Now;
sw.WriteLine("{0}\t{1}\tMESSAGE:{2}",
dt.ToShortDateString(),
dt.ToLongTimeString(),
logEntry);
sw.Flush();
}
}