2009-07-18 3 views
5

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

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

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

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

Спасибо!

ответ

7

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

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

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

Как только это будет сделано, то для каждого метода обслуживания вы хотите, чтобы понять, печенье 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, а также очевидно.

+0

Выглядит хорошо; вам известно, можно ли использовать это (или что-то подобное) при использовании raw httpwebrequest? У меня есть собственный стек RPC, который я бы хотел защитить таким же образом (я могу, конечно, спросить, как новый квест, если это нетривиальный ответ) –

+0

Он должен делать «да»; см. http://www.silverlightshow.net/items/Cookies-in-Silverlight-Web-Requests.aspx – blowdart

+0

Ta; Я посмотрю на это; -p –

0

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

1

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

Ознакомьтесь с функциями безопасности 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 и имеет множество вариантов - это может быть немного сложной задачей, но, в конце концов, обычно это имеет смысл! :-)

Марк

+6

Я не уверен, в каком сценарии вы могли это сделать, но по моему опыту это не разрешено в WCF. Вы не можете использовать безопасность имени пользователя-пароля в режиме basicHttpBinding, она запрещена фреймворком, потому что учетные данные будут передаваться в виде обычного текста. Вы получите это InvalidOperationException: «Для привязки к BasicHttp требуется, чтобы BasicHttpBinding.Security.Message.ClientCredentialType был эквивалентен типу учетных данных BasicHttpMessageCredentialType.Certificate для защищенных сообщений. Выберите« Транспорт »или« TransportWithMessageCredential »для учетных данных UserName». – Grank

Смежные вопросы