wcf данные контракты авторизация - PullRequest
4 голосов
/ 19 февраля 2011

как использовать атрибут [PrincipalPermission(SecurityAction.Demand, Role = "Administrators")] в классе?

Я ищу способ ограничить доступ к моему объекту, т. Е. Если к какому-либо объекту обращаются в методе сервиса и если у пользователя есть права на доступ к методу сервиса, но нет прав на доступ к объекту иисключение должно быть выброшено

Ответы [ 2 ]

5 голосов
/ 28 февраля 2011

PrincipalPermission атрибут может украшать метод или класс. Поэтому возможно ограничить доступ к экземпляру объекта. Необходимо сделать несколько вещей:

  1. Настройка выбранной службы и привязки клиента для использования безопасности. Укажите Windows в качестве типа учетных данных клиента.
  2. Настройка службы для использования групп Windows для авторизации.
  3. Украсьте класс, который будет содержать конфиденциальную информацию с атрибутом PrincipalPermission.

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

  1. Создание экземпляра службы singleton. Thread.CurrentPrincipal должен иметь разрешения, необходимые для доступа к конфиденциальному объекту.
  2. Создать ServiceHost экземпляр, передав сервисный экземпляр singleton. Свойство InstanceContextMode атрибута ServiceBehavior должно быть установлено на InstanceContextMode.Single.

В противном случае:

  1. Создать ServiceHost экземпляр, передав тип сервиса.

При желании, украсьте метод обслуживания атрибутом FaultContract и выведите из него FaultException, чтобы избежать сбоя в клиентском канале.

Вот пример:

Файл конфигурации службы :

<system.serviceModel>
    <services>
        <service name="Server.Service" behaviorConfiguration="Authorization">
            <endpoint address=""
                      binding="netTcpBinding" bindingConfiguration="TCP"
                      contract="Common.IService" />
            <host>
                <baseAddresses>
                    <add baseAddress="net.tcp://localhost:13031/Service"/>
                </baseAddresses>
            </host>
        </service>
    </services>
    <bindings>
        <netTcpBinding>
            <binding name="TCP" openTimeout="00:30:00" closeTimeout="00:00:10" maxReceivedMessageSize="2147483647">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
                <security mode="Message">
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="Authorization">
                <serviceAuthorization principalPermissionMode="UseWindowsGroups" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

Файл конфигурации клиента :

<system.serviceModel>
    <client>
        <endpoint name="NetTcpBinding_IService"
                  address="net.tcp://localhost:13031/Service"
                  binding="netTcpBinding" bindingConfiguration="TCP"
                  contract="Common.IService" />
    </client>
    <bindings>
        <netTcpBinding>
            <binding name="TCP" openTimeout="00:30:00" closeTimeout="00:00:10" sendTimeout="00:30:00" receiveTimeout="00:30:00" maxReceivedMessageSize="2147483647">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
                <security mode="Message">
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
</system.serviceModel>

Класс конфиденциальной информации :

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators" ) ]
public class ContactInfo
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public ContactInfo()
    {
        FirstName = "John";
        LastName = "Doe";
    }
    public override string ToString()
    {
        return string.Format( "{0} {1}", FirstName, LastName );
    }
}

Сервисный договор и его реализация :

[ServiceContract]
public interface IService
{
    [OperationContract]
    [FaultContract( typeof( string ) )]
    string GetName( int id );
}

[ServiceBehavior]
// Use following if singleton instance needs to be passed to `ServiceHost` constructor
//[ServiceBehavior( InstanceContextMode = InstanceContextMode.Single )]
public class Service : IService
{
    private Dictionary<int, ContactInfo> Contacts { get; set; }
    public Service()
    {
        Contacts = new Dictionary<int, ContactInfo>();
        IPrincipal originalPrincipal = Thread.CurrentPrincipal;
        try
        {
            Thread.CurrentPrincipal = new WindowsPrincipal( WindowsIdentity.GetCurrent() );
            Contacts.Add( 1, new ContactInfo() );
        }
        finally
        {
            Thread.CurrentPrincipal = originalPrincipal;
        }
    }
    public string GetName( int id )
    {
        if ( Contacts.Count < id )
            return null;
        try
        {
            return Contacts[ id ].ToString();
        }
        catch ( Exception ex )
        {
            throw new FaultException<string>( ex.Message );
        }
    }
}
1 голос
/ 19 февраля 2011

Если вы знакомы с кодированием разрешений .NET (императивным или декларативным), шаблон точно такой же. В декларативной форме атрибут PrincipalPermissionAttribute применяется к методу в классе, который реализует контракт службы:

[PrincipalPermission(SecurityAction.Demand, Role = "Updaters")]
public bool Update()
{
return true;
}

В этом примере текущий участник проверяется, чтобы определить, принадлежит ли он роли, называемой Updaters. В фактической реализации атрибута вызывается метод IsInRole на принципале.

Для обязательного определения PrincipalPermissionAttribute создается экземпляр класса PrincipalPermission. Конструктор для PrincipalPermission принимает имя пользователя и роль в качестве параметра. При создании экземпляра можно вызвать метод Demand, чтобы определить, имеет ли текущий участник необходимые разрешения. Следующий код предоставляет пример:

PrincipalPermission p = new PrincipalPermission(null, "Updaters");
p.Demand();

конфигурация должна выглядеть следующим образом:

<behaviors>
  <serviceBehaviors>
    <behavior>
      ...
      <serviceAuthorization principalPermissionMode="UseWindowsGroups" />
    </behavior>
  </serviceBehaviors>
</behaviors>

для рабочего образца смотрите: Авторизация доступа к сервисным операциям

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...