最近,我的任务是在将传统文档格式转换为 PDF 时解决隐私问题。
问题非常严重:当多个用户同时访问转换服务时,有时他们的文件会被交换。
想象一下,当汤姆收到杰瑞的文件时,会有多惊讶(和隐私噩梦),反之亦然。
出现此问题的原因是,我们在同一台计算机上运行了两个 ASP.NET 应用程序,它们都共享相同的转换器应用程序。
管理层希望快速解决这一隐私问题。
经过一番思考,我决定互斥锁将是解决这个问题的最有效方法。
这个想法很简单:确保文档转换过程一次只能由一个应用程序访问,即使多个应用程序尝试同时访问它。
这种方法将消除文件交换问题,并确保用户数据保持私密。
互斥锁是一种同步机制,可确保一次只有一个线程或进程可以进入特定的代码段。
但是,由于两个 ASP .NET 应用程序正在访问同一资源,因此我们需要配置 Mutex 以允许在这两个应用程序之间共享。
必须配置两件事:互斥锁访问规则和互斥锁名称。这些将允许互斥锁在两个不同的应用程序之间安全地共享。
这里的关键是 的用法。这将使互斥锁能够在两个应用程序之间安全地共享,这两个应用程序由相同的 IIS 用户帐户运行。WellKnownSidType.BuiltinUsersSid
var accessRule = new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
MutexRights.FullControl,
AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(accessRule);
我们还可以使用 来扩大范围。但是,它将不太安全,因为计算机上的任何人都可以访问互斥锁。
要在应用程序之间共享相同的互斥锁,我们必须确保正确设置了互斥锁名称。
using (var mutex = new Mutex(false, "Global\\PdfConversion", out _, securitySettings))
{
// ...
}
互斥名称在应用程序之间必须相同,并且必须具有前缀,以确保它在计算机上的所有会话中都是可见的。
配置了访问规则和名称后,我们继续创建互斥锁实现:
var accessRule = new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
MutexRights.FullControl,
AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(accessRule);
using (var mutex = new Mutex(false, "Global\\PdfConversion", out _, securitySettings))
{
try
{
// Attempt to acquire the mutex
// Waiting up to 2 minutes for availability
mutex.WaitOne(120000);
// If acquired, run the document conversion process
return RunConversion(doc);
}
catch (AbandonedMutexException)
{
// If the mutex was abandoned, release it and try to acquire it again
mutex.ReleaseMutex();
// Wait again up to 2 minutes for the mutex
mutex.WaitOne(120000);
// Once acquired, re-run the document conversion process
return RunConversion(doc);
}
finally
{
// Always release the mutex when done to allow other processes to use the resource
mutex.ReleaseMutex();
}
}
我使用 PowerShell 命令同时运行了多个请求以测试应用程序:
Start-Job {Invoke-WebRequest -Uri https://localhost:1000/api/download/1 -OutFile C:\\file1.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:1000/api/download/2 -OutFile C:\\file2.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:2000/api/download/3 -OutFile C:\\file3.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:2000/api/download/4 -OutFile C:\\file4.pdf}
...etc
在执行测试和回归后,修补程序已部署到生产环境。通过一个相对简单的解决方案解决了复杂的隐私问题。