随着IIS7的发布,IIS自带的FTP终于能自定义验证了.
目前知道的自定义接口共三个 自定义校验, 自定义主目录,自定义日志
分别是 Microsoft.Web.FtpServer的
IFtpAuthenticationProvider,
IFtpRoleProvider
主目录: IFtpHomeDirectoryProvider
日志的没测试, 可以在WWW.IIS.NET直接找到的
步骤:
1. 首先创建 C#类库 (要选择 2.0 / 3.5 框架) ,有说 .NET 4.0不支持 ,但是这个没做验证,需要后期继续测试
2. 然后增加生成事件 后期处理 VS2012版本:
net stop ftpsvc
call "%VS110COMNTOOLS%\vsvars32.bat">null
gacutil.exe /if "$(TargetPath)"
net start ftpsvc VS2013 =vs120 ,其他版本递减
3. 添加签名(无密码)
4. 代码
namespace FtpHomeDirectory
{
public class FtpHomeDirDemo : BaseProvider,
IFtpHomeDirectoryProvider
{
string IFtpHomeDirectoryProvider.GetUserHomeDirectoryData(
string sessionId,
string siteName,
string userName)
{
// Note: You would add your own custom logic here.
// Return the user‘s home directory based on their user name.
string homedir = @"D:\Ftptest\" + userName;
VASLog.WriteLog_day(@"d:\Ftptest", "ftplog", "siteName: " + siteName + " 用户想要得到的目录是:"+homedir+" ;");
return homedir;
}
}
{
public class FtpHomeDirDemo : BaseProvider,
IFtpHomeDirectoryProvider
{
string IFtpHomeDirectoryProvider.GetUserHomeDirectoryData(
string sessionId,
string siteName,
string userName)
{
// Note: You would add your own custom logic here.
// Return the user‘s home directory based on their user name.
string homedir = @"D:\Ftptest\" + userName;
VASLog.WriteLog_day(@"d:\Ftptest", "ftplog", "siteName: " + siteName + " 用户想要得到的目录是:"+homedir+" ;");
return homedir;
}
}
}
密码验证
namespace FtpAuthenticationDemo
{
public class FtpAuthDemo : BaseProvider,
IFtpAuthenticationProvider,
IFtpRoleProvider
{
//void IFtpLogProvider.Log(FtpLogEntry loggingParameters)
//{
// // Note: You would add your own custom logic here.
// // Open the log file for output.
// using (StreamWriter sw =
// new StreamWriter(@"C:\inetpub\logs\LogFiles\FTPSVC8\myftplog.log", true))
// {
// // Retrieve the current date and time for the log entry.
// DateTime dt = DateTime.Now;
// // Retrieve the user name.
// string un = loggingParameters.UserName;
// // Write the log entry to the log file.
// sw.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
// dt.ToShortDateString(),
// dt.ToLongTimeString(),
// loggingParameters.RemoteIPAddress,
// (un.Length == 0) ? "-" : un,
// loggingParameters.Command,
// loggingParameters.SessionId);
// }
//}
bool IFtpAuthenticationProvider.AuthenticateUser(
string sessionId,
string siteName,
string userName,
string userPassword,
out string canonicalUserName)
{
// Note: You would add your own custom logic here.
canonicalUserName = userName;
//string strUserName = "test";
//string strPassword = "123";
VASLog.WriteLog_day(@"d:\Ftptest", "ftplog", canonicalUserName + " siteName: " +siteName +" 校验总是可以成功的;");
return true;
// Verify that the user name and password are valid.
// Note: In this example, the user name is case-insensitive
// and the password is case-sensitive.
//if (((userName.Equals(strUserName,
// StringComparison.OrdinalIgnoreCase)) == true) &&
// userPassword == strPassword)
//{
// return true;
//}
//else
//{
// return true;
//}
}
bool IFtpRoleProvider.IsUserInRole(
string sessionId,
string siteName,
string userName,
string userRole)
{
// Note: You would add your own custom logic here.
string strUserName = "MyUser";
string strRoleName = "MyRole";
//VASLog.WriteLog_day(@"d:\Ftptest", "ftplog", "IsUserInRole");
return true;
// Verify that the user name and role name are valid.
// Note: In this example, both the user name and
// the role name are case-insensitive.
if (((userName.Equals(strUserName,
StringComparison.OrdinalIgnoreCase)) == true) &&
((userRole.Equals(strRoleName,
StringComparison.OrdinalIgnoreCase)) == true))
{
return true;
}
else
{
return false;
}
}
//string IFtpHomeDirectoryProvider.GetUserHomeDirectoryData(
// string sessionId,
// string siteName,
// string userName)
//{
// VASLog.WriteLog_day(@"d:\Ftptest", "ftplog", "GetUserHomeDirectoryData");
// // Note: You would add your own custom logic here.
// // Return the user‘s home directory based on their user name.
// return @"d:\FtpTest\" + userName;
//}
}
{
public class FtpAuthDemo : BaseProvider,
IFtpAuthenticationProvider,
IFtpRoleProvider
{
//void IFtpLogProvider.Log(FtpLogEntry loggingParameters)
//{
// // Note: You would add your own custom logic here.
// // Open the log file for output.
// using (StreamWriter sw =
// new StreamWriter(@"C:\inetpub\logs\LogFiles\FTPSVC8\myftplog.log", true))
// {
// // Retrieve the current date and time for the log entry.
// DateTime dt = DateTime.Now;
// // Retrieve the user name.
// string un = loggingParameters.UserName;
// // Write the log entry to the log file.
// sw.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
// dt.ToShortDateString(),
// dt.ToLongTimeString(),
// loggingParameters.RemoteIPAddress,
// (un.Length == 0) ? "-" : un,
// loggingParameters.Command,
// loggingParameters.SessionId);
// }
//}
bool IFtpAuthenticationProvider.AuthenticateUser(
string sessionId,
string siteName,
string userName,
string userPassword,
out string canonicalUserName)
{
// Note: You would add your own custom logic here.
canonicalUserName = userName;
//string strUserName = "test";
//string strPassword = "123";
VASLog.WriteLog_day(@"d:\Ftptest", "ftplog", canonicalUserName + " siteName: " +siteName +" 校验总是可以成功的;");
return true;
// Verify that the user name and password are valid.
// Note: In this example, the user name is case-insensitive
// and the password is case-sensitive.
//if (((userName.Equals(strUserName,
// StringComparison.OrdinalIgnoreCase)) == true) &&
// userPassword == strPassword)
//{
// return true;
//}
//else
//{
// return true;
//}
}
bool IFtpRoleProvider.IsUserInRole(
string sessionId,
string siteName,
string userName,
string userRole)
{
// Note: You would add your own custom logic here.
string strUserName = "MyUser";
string strRoleName = "MyRole";
//VASLog.WriteLog_day(@"d:\Ftptest", "ftplog", "IsUserInRole");
return true;
// Verify that the user name and role name are valid.
// Note: In this example, both the user name and
// the role name are case-insensitive.
if (((userName.Equals(strUserName,
StringComparison.OrdinalIgnoreCase)) == true) &&
((userRole.Equals(strRoleName,
StringComparison.OrdinalIgnoreCase)) == true))
{
return true;
}
else
{
return false;
}
}
//string IFtpHomeDirectoryProvider.GetUserHomeDirectoryData(
// string sessionId,
// string siteName,
// string userName)
//{
// VASLog.WriteLog_day(@"d:\Ftptest", "ftplog", "GetUserHomeDirectoryData");
// // Note: You would add your own custom logic here.
// // Return the user‘s home directory based on their user name.
// return @"d:\FtpTest\" + userName;
//}
}
}
尽量两个分开吧
生成后,在输出里可以看到
1>
1> Microsoft (R) .NET Global Assembly Cache Utility. Version
4.0.30319.17929
1> 版权所有(C) Microsoft Corporation。保留所有权利。
1>
1> 程序集已成功添加到缓存中
1> Microsoft FTP Service 服务正在启动 .
1> Microsoft FTP Service 服务已经启动成功。
然后要做的,就是配置IIS了
1. 在IIS的根基目录中,配置 FTP身份验证,禁用其他选项,在右侧自定义提供程序中,注册刚才的DLL,
2. FTP规则里,允许所有账户
3. 同样的注册主目录DLL
4. 跟密码验证不同,主目录的DLL,还需要设置两个地方
http://www.iis.net/learn/develop/developing-for-ftp/how-to-use-managed-code-c-to-create-a-simple-ftp-home-directory-providercd %systemroot%/system32/Inetsrv/
AppCmd set site "YourFTP" /+ftpServer.customFeatures.providers.[name=‘FtpHomeDirectoryDemo‘,enabled=‘true‘]
AppCmd set site "YourFTP" /ftpServer.userIsolation.mode:Custom
注意: 第一个appcmd 里面的 name = ftphomedirectorydemo 这个name,是在上面注册在IIS里的名称,跟DLL的空间类名没关系,一定要注意
这样设置之后,才能启用主目录的设置
5. 在FTP用户隔离里,选择 下面的 用户名目录(禁用全局虚拟目录) ,这个用不用,还不知道,有待测试! 原理上考虑,这个其实没作用了,毕竟主目录在DLL里,已经可以定义了