Пользовательский атрибут .NET для олицетворения?
-
18-09-2019 - |
Вопрос
У меня есть несколько методов, которые необходимо запускать от имени определенной учетной записи службы, поэтому я делаю обычные вещи:
public DoSomeWorkAsServiceAccount() {
...
// assume I am given tokenHandle
WindowsIdentity newId = new WindowsIdentity(tokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
...
// do the work here
...
impersonatedUser.Undo();
}
Мне бы хотелось избежать написания этого кода в каждом методе, поэтому я подумал о создании собственного атрибута:
[Impersonate(tokenHandle)]
public DoSomeWorkAsServiceAccount() {
// do the work
}
Итак, вот мои вопросы:
- Это возможно?
- Можете ли вы показать мне что-нибудь, что позволит избежать дублирования кода?
Заранее спасибо.
Решение
Я не думаю, что атрибут — лучший способ реализовать такую функцию.По большей части атрибуты просто действуют как метаданные типов и членов (за исключением аспектно-ориентированных элементов).Вам нужно будет написать что-то для проверки этого атрибута и соответствующим образом перенаправить вызов метода.Если у вас уже есть какой-то код АОП, это не должно быть большой утомительной работой, но если у вас его нет, вам, вероятно, будет гораздо лучше, если вы сделаете что-то вроде этого:
public void DoWorkAsUser(tokenHandle, Action op)
{
WindowsIdentity newId = new WindowsIdentity(tokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
op();
impersonatedUser.Undo();
}
И затем назовите это так:
DoWorAsUser(token, MyMethod);
Это позволяет вам централизовать код олицетворения без необходимости возиться с отражением, переплетением кода и т. д.
Другие советы
У меня нет кода, но вы можете попробовать использовать ПостШарп сделать это.Вы можете создать OnMethodInvocateAspect, который организует элементы безопасности перед вызовом кода метода.например
public class ImpersonateAttribute : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
WindowsIdentity newId = new WindowsIdentity(tokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
eventArgs.Proceed() // Call the code in the actual method.
impersonatedUser.Undo();
}
}
Вышеупомянутое является полным предположением, но, предложив его, я, возможно, дал вам действительный вариант.