Вопрос

У меня есть несколько методов, которые необходимо запускать от имени определенной учетной записи службы, поэтому я делаю обычные вещи:

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
}

Итак, вот мои вопросы:

  1. Это возможно?
  2. Можете ли вы показать мне что-нибудь, что позволит избежать дублирования кода?

Заранее спасибо.

Это было полезно?

Решение

Я не думаю, что атрибут — лучший способ реализовать такую ​​функцию.По большей части атрибуты просто действуют как метаданные типов и членов (за исключением аспектно-ориентированных элементов).Вам нужно будет написать что-то для проверки этого атрибута и соответствующим образом перенаправить вызов метода.Если у вас уже есть какой-то код АОП, это не должно быть большой утомительной работой, но если у вас его нет, вам, вероятно, будет гораздо лучше, если вы сделаете что-то вроде этого:

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();
  }
}

Вышеупомянутое является полным предположением, но, предложив его, я, возможно, дал вам действительный вариант.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top