Поведение SecurityManager.IsGranted()
Кто-нибудь может объяснить, пожалуйста, следующее поведение C#? Я написал небольшое консольное приложение, чтобы узнать о CAS, но не могу понять, почему следующие строки кода работают так, как они:
string[] myRoles = new string[] { "role1", "role2", "role3" };
GenericIdentity myIdentity = new GenericIdentity("myUsername", "customAuthType");
GenericPrincipal myPrincipal = new GenericPrincipal(myIdentity, myRoles);
System.Threading.Thread.CurrentPrincipal = myPrincipal;
Console.WriteLine(SecurityManager.IsGranted(new PrincipalPermission(null, "role1")));
Console.WriteLine(SecurityManager.IsGranted(new PrincipalPermission(null, "roleX")));
Вывод "true" для обоих вызовов SecurityManager.IsGranted().
Если я тогда добавлю следующие строки:
new PrincipalPermission(null, "role1").Demand();
new PrincipalPermission(null, "roleX").Demand();
первый вызов по требованию проходит, но второй (как и ожидалось) вызывает исключение SecurityException.
Почему SecurityManager.IsGranted() не возвращает false для разрешения roleX?
3 ответа
В.NET 4.0 SecurityManager.IsGranted был сделан устаревшим.
Это то, что было, и если вы скомпилируете в.NET 4.0 совместимость, он будет жаловаться.
bool isGranted = SecurityManager.IsGranted(new SecurityPermission(SecurityPermissionFlag.Infrastructure))
Починить это:
var permissionSet = new PermissionSet(PermissionState.None);
permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode));
bool isGranted = permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet);
Ссылка:
http://www.stringbuilder.net/post/2009/07/31/In-NET-40-SecurityManagerIsGranted-is-obsolete.aspx
Из ответов на аналогичный вопрос здесь видно, что IsGranted() работает только с разрешениями CAS, но не с разрешениями не-CAS.
Цитаты из статьи:
SecurityManager.IsGranted() определяет, будет ли предоставлено разрешение, изучив разрешения CAS, предоставленные администратором. Поскольку WorkingTimePermission является разрешением, отличным от CAS, это означает, что политики безопасности, установленные администратором, не влияют на это разрешение. Другими словами, администратор не может предоставить или отозвать [разрешение не-CAS]. Поэтому SecurityManager.IsGranted() всегда будет возвращать false для [разрешения не-CAS].
а также
Мне потребовалось некоторое время, чтобы привыкнуть к CAS вместо разрешений, отличных от CAS, и понять, что ключевые фразы, такие как "политики безопасности" и "политика", применяются только к разрешениям CAS. Как только я освоился с этим, расшифровать явно невинные записи справки, такие как SecurityManager. Раздел примечаний IsGranted стал намного проще:
"Предоставление разрешений определяется политикой..."
Это подразумевает, но не указывает явно, что метод работает только с разрешениями CAS, потому что он проверяет текущую политику безопасности. Требуется некоторое привыкание.
Я верю SecurityManager.IsGranted
в основном рассматривает требования к коду (сборка и т. д.), а не конкретные требования, такие как основные разрешения.
Чтобы делать то, что вы хотите:
static bool HasAccess(string role)
{
IPrincipal principal = System.Threading.Thread.CurrentPrincipal;
return principal == null ? false : principal.IsInRole(role);
}