参考:
http://gzzhang.blog.51cto.com/5312382/1125092
随着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;
}
}
}
密码验证
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;
//
}
}
}
尽量两个分开吧
生成后,在输出里可以看到
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,
http://www.iis.net/learn/develop/developing-for-ftp/how-to-use-managed-code-c-to-create-a-simple-ftp-authentication-provider
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-provider
cd %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的空间类名没关系,一定要注意
禁用缓存,以管理员身份运行:
cd /d "%SystemRoot%\System32\Inetsrv"
Appcmd.exe set config -section:system.ftpServer/caching /credentialsCache.enabled:"False" /commit:apphost
这个一定要执行,不然,修改了数据库的密码之后,依然旧密码要保留一点时间,但是原因是什么,不理解.
现象,好像是登录时,直接就过了验证,进入到了目录获取的地方去了.
这样设置之后,才能启用主目录的设置
5. 在FTP用户隔离里,选择 下面的 用户名目录(禁用全局虚拟目录) ,这个用不用,还不知道,有待测试! 原理上考虑,这个其实没作用了,毕竟主目录在DLL里,已经可以定义了