jrista прав - вы можете использовать встроенные службы авторизации Windows, включая атрибут «PrincipalPermission», чтобы ограничить доступ.
НО: прежде чем вы сможете авторизоваться, вам необходимо пройти аутентификацию. Прежде всего вам необходимо знать, кто стучится в дверь вашей службы, прежде чем решить, впустить его (или ее) или нет.
Для этого необходимо использовать учетные данные Windows при обмене сообщениями, а клиент и сервер должны находиться в одном домене (или в доменах с отношениями взаимного доверия). Кроме того, вам необходимо использовать привязку, например wsHttp или netTcp, которая по умолчанию разрешает и поддерживает учетные данные Windows, и вам необходимо убедиться, что вы используете и настраиваете конфигурацию безопасности привязки, которая передает учетные данные Windows от клиента к серверу.
Вам понадобится что-то вроде:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="Secured">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
и затем вам нужно будет сослаться на эту конфигурацию привязки от конечных точек вашего клиента и сервера.
WsHttpBinding и NetTcpBinding по умолчанию используют учетные данные клиента Windows, поэтому из коробки, если вы полностью не отключили защиту, вы должны получить поддержку учетных данных Windows в этих двух привязках.
Марк
PS:
Как показывает jrista (как я уже делал в предыдущем ответе на почти такой же вопрос , что у вас был), вам действительно нужно только добавить этот атрибут PrincipalPermission в методы, которые вы хотите ограничить для пользователей, принадлежащих к определенной группе. - не нужно вручную возиться с членством в группе AD и т. д.
Если вы действительно должны получить группы, к которым принадлежит пользователь, вызывающий вашу службу, вы можете проверить свойство ".Groups" WindowsIdentity, которое вызывает:
WindowsIdentity winCaller = ServiceSecurityContext.Current.WindowsIdentity;
foreach(var group in winCaller.Groups)
{
Console.WriteLine(group.Value);
}
Если вам нужно имя пользователя, который звонит, используйте winCaller.Name
. Если вам нужен SID для вызова пользователя, используйте winCaller.User
. Там все в порядке - без проблем, без сложного кода - просто используйте его! : -)