Как я могу определить, должен ли мой код олицетворять или нет?
У меня есть код, который выполняется как часть обработчика событий и ему нужно создать новый сеанс TOM.NET(я не могу повторно использовать subject.Session
). Этот обработчик событий загружается во многие процессы Tridion (TcmServiceHost, COM +, Publisher, TcmTemplateDebugHost, пул приложений IIS), и эти процессы могут:
- выполняется под идентификатором, имеющим доступ к Tridion (например, приложение COM + выполняется под MTSUser, которое является администратором Tridion)
- выполняется под идентификатором, который не имеет доступа к Tridion, но ему разрешено выдавать себя за пользователей Tridion (например, TcmServiceHost работает как NetworkService, который настроен как пользователь олицетворения Tridion).
Я пытаюсь удовлетворить оба случая с помощью этого кода TOM.NET:
Session session = null;
try
{
session = new Session();
}
catch (AccessDeniedException ex)
{
// this process doesn't have TCM access, so impersonate a user that does
session = new Session("Administator");
}
if (session != null)
{
var item = session.GetObject(id);
...
Правильно ли это проверить, работает ли мой код в процессе, который имеет доступ к Tridion (игнорируя тот факт, что я жестко закодирован "Администратор" )? Код работает, но мне просто интересно, есть ли более эффективный способ выполнить проверку "имеет доступ к Tridion"?
Примечание: тот же вопрос возникает, когда я использую базовую услугу для доступа к Tridion, поэтому вопрос заключается не в том, является ли TOM.NET правильным API для использования здесь.
Ответы
Ответ 1
Я бы не использовал этот код. Захват исключений медленный, и вы в настоящее время предоставляете (администратору) доступ ко всем, кто не может получить доступ к системе, - это большая дыра в безопасности.
Вместо этого я бы посмотрел, кто такой текущий пользователь, и выяснить, является ли он пользователем олицетворения или нет. Вы можете напрямую прочитать пользователей-олигархов из файла Tridion.ContentManager.config, если для него нет API (я еще не проверял).
var isImpersonationUser = IsImpersonationUser(WindowsIdentity.GetCurrent());
var session = isImpersonationUser ? new Session("Administrator") : new Session();
var item = session.GetObject(id);
Или вы можете настроить его отдельно для кода события. Или даже жестко закодированный, если вам не нужен общий код.
Ответ 2
Этот код кажется мне очень эффективным, но, проверяя, можете ли вы создать объект сеанса, ни в коем случае не гарантируйте, что код сможет выполнить действие, которое вы хотите выполнить на CMS.
Также кажется, что такой код создает большую уязвимость безопасности, позволяющую процессам отступать к более высокому уровню безопасности, когда у них нет разрешений. Также имейте в виду, что если вы изменяете какие-либо элементы в CMS, это олицетворение будет иметь результат не показывать реальное имя человека, которое могло вызвать изменение. Он будет сохранен в качестве пользователя, которого вы выдаете.
Ответ 3
Прежде всего, это отличный вопрос/тема.
Я думаю, что вы пытаетесь "построить" нечто общее, которое может работать на каждом процессе Tridion. На мой взгляд, вы должны знать, когда находитесь в том или ином процессе, поскольку на основе Best Practices (R & D/you) мы не должны создавать объекты сеанса, а использовать Core Service в тех процессах, t иметь доступ к объекту Session и использовать доступный сеанс, когда это возможно.
Как вы знаете, в системе Templating and Event System, например, у нас есть доступ к сеансу, поэтому мы должны повторно использовать его (если мы не хотим делать то, что пользователю не разрешено делать, и в этом случае мы должны выдавать себя за него),
Если в другом процессе сеанс недоступен, вы должны использовать Core Service.
Итак, мой ответ на ваш вопрос - не использовать TOM.NET. Я бы изменил свой подход и построил его с помощью Core Service, где я могу выдавать себя за конкретного пользователя, которого я уже настроил ранее. И ваш код будет более общим и будет работать "везде" (но не в тостере).
Я понимаю, что вы пытаетесь идентифицировать здесь, "кто, черт возьми, работает мой текущий процесс"? поэтому вы можете выдавать себя соответственно,
К сожалению (AFAIK) вам нужно будет написать код, чтобы узнать, кто является идентификатором, выполняющим этот процесс, а затем выдавать себя за него. Это сложно, и это опять же, почему я бы рекомендовал использовать Core Service вместо TOM.NET API.
Надеюсь, что это имеет смысл.
Ответ 4
Назад, когда первоначально был реализован метод TDSE.Impersonate(), он был сознательно разработан для отказа в молчании, если идентификатор вызывающей нити не был пользователем олицетворения. Это позволило, например, ASP-код в графическом интерфейсе дня слепо пытаться олицетворять (на основе REMOTE_USER заголовка IIRC). Дело в том, что если вы не являетесь олицетворением пользователя, хорошо, хорошо, вы могли бы быть самим собой, но если бы вы были, вы могли бы/вылились бы в лицо.
Я только что протестировал это с помощью COM API (я оставлю его вам, чтобы убедиться, что .NET API согласован). Мои результаты (на Tridion 2011 SP1) следующие:
1). Пользователь олицетворения, который является доверенным лицом и не олицетворяет себя, становится сам собой.
2). Пользователь олицетворения, который является опекуном и олицетворяет собой, становится тем, кем они олицетворяют (N.B. Обычно вы предпочитаете не создавать такого пользователя).
3). Пользователь без олицетворения, который вызывает олицетворения, остается сам.
Очевидно, что многое зависит от того, является ли идентификатор процесса олицетворением пользователя. Возможно, есть сценарии, в которых вы можете предпочесть избегать использования NETWORK SERVICE и явно создавать идентификатор для TcmServiceHost, просто чтобы обеспечить мелкомасштабный контроль над тем, может ли такой пользователь выдавать себя.
Итак... нужно ли вам явно проверить, запущен ли ваш процесс в качестве имитатора? Лучше просто попытаться олицетворить и принять результат. Первоначальное мышление, безусловно, включало это намерение, но я подозреваю, что с тех пор все стало более сложным.
+1 для вопроса, потому что совершенно необходимо, чтобы в этой области не было сомнений относительно ожидаемого поведения.