WCF + учетные данные пользователя - PullRequest
5 голосов
/ 18 июля 2009

Я работаю над веб-приложением Silverlight v3 и хотел бы обеспечить безопасный доступ к службе WCF, которую я использую для получения своих данных. В настоящее время WCF работает нормально, но для этого не требуются учетные данные пользователя.

Я не очень разбираюсь в этом аспекте WCF, поэтому моей первой идеей было добавить параметры имени пользователя и пароля для каждой операции моей службы. Проблема, с которой я столкнулся, заключается в том, что для этого потребуется много избыточного кода, а также тот факт, что имя пользователя и пароль будут передаваться по сети в виде простого текста.

То, что я хотел бы, это способ указать учетные данные заранее на стороне клиента сразу после создания прокси-сервера службы (я использую прокси-сервер, автоматически созданный из «Добавить ссылку на службу»).

После поиска решения этой проблемы я смог найти только те решения, которые были бы похожи на мою первую идею (с использованием параметров имени пользователя / пароля). Может ли кто-нибудь указать мне правильное направление?

Спасибо!

Ответы [ 3 ]

7 голосов
/ 18 июля 2009

Откуда эти имена пользователей и пароли? Если на вашем веб-сайте уже реализована проверка подлинности с помощью форм, вы можете самостоятельно обойти настройки учетных данных и использовать файл cookie проверки подлинности с помощью форм. Если ваши пользователи вошли в систему, тогда cookie отправится вместе с вызовом веб-службы. Чтобы прочитать его с другой стороны, нужно внести пару изменений.

Сначала необходимо включить режим совместимости ASP.NET для WCF в разделе system.ServiceModel:

<system.serviceModel>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
</system.serviceModel>

Как только это будет сделано, для каждого метода службы, который вы хотите понять, файл cookie ASP.NET, добавьте атрибут [AspNetCompatibilityRequirements] в свой класс службы

[ServiceContract]
[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ExampleService
{
}

Теперь внутри каждого метода вы можете получить доступ к объекту HttpContext.Current.User.Identity, чтобы узнать личность пользователя.

Если вы хотите, чтобы аутентифицированные пользователи вызывали только определенные методы, то вы можете использовать PrincipalPermission, таким образом

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
public string Echo()

В качестве бонуса, если вы используете поставщик ролей ASP.NET, они также будут заполнены, и вы сможете использовать PrincipalPermission для методов, чтобы ограничить их членами определенной роли:

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role="Administators")]
public string NukeTheSiteFromOrbit()

И это очевидно работает и в Silverlight2.

1 голос
/ 18 июля 2009

Не бросайте свои собственные и не добавляйте явные параметры - это действительно слишком много работы!

Ознакомьтесь с функциями безопасности WCF - их много! Вы можете, например, Защитите сообщение и включите в него учетные данные - все из коробки, никакого дополнительного кодирования на вашей стороне не требуется!

Прочтите эту прекрасную статью о безопасности WCF, написанную Мишелем Леру Бустаманте: http://www.devx.com/codemag/Article/33342

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

На стороне сервера:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="YourService">
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
  </service>
</services>

И вам нужно применить те же настройки на стороне клиента:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
</client>

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

YourServiceClient client = new YourServiceClient();

client.ClientCredentials.UserName.UserName = "your user name";
client.ClientCredentials.UserName.Password = "top$secret";

На стороне сервера вам необходимо настроить способ проверки этих учетных данных пользователя - обычно в отношении домена Windows (Active Directory) или модели поставщика членства ASP.NET. В любом случае, если учетные данные пользователя не могут быть проверены по указанному вами хранилищу, вызов будет отклонен.

Надеюсь, это немного поможет - безопасность является большой темой в WCF и имеет множество опций - это может быть немного утомительно, но, в конце концов, обычно это имеет смысл! : -)

Марк

0 голосов
/ 18 июля 2009

вы можете передать какой-то объект аутентификации и зашифровать его на уровне сообщения с помощью WCF. C # аспекты (http://www.postsharp.org/) могут затем использоваться, чтобы избежать избыточной логики. Это очень чистый способ обработки.

...