Как позвонить в веб-сервис с использованием сохраненных учетных данных? - PullRequest
3 голосов
/ 15 июня 2009

Мне нужно вызвать веб-службу, работающую в домене Windows, который отличается от того, в котором работает клиент (Windows Forms). Веб-служба защищена с помощью проверки подлинности Windows.

Учетные данные домена для домена веб-службы сохраняются в профиле пользователя клиента (сохраненные имена пользователей и пароли в XP), но я не смог выяснить, как использовать эти сохраненные учетные данные при вызове веб-службы. Я нашел много примеров использования

WebService1.Credentials = System.Net.CredentialCache.DefaultCredentials 

(это не работает, потому что это учетные данные для локального домена)

или

WebService1.Credentials = new NetworkCredentials(username, pwd, domain) 

(были жестко заданы имя пользователя, пароль, домен).

Я прочитал об использовании CredEnumerate и CredRead с использованием Windows API, но не знаю, как (или если) я могу преобразовать PCREDENTIAL в управляемый NetworkCredential (ReadCred вон) вернуть пароли для сохраненных учетных данных домена)

Кто-нибудь здесь на SO знает, как это сделать?

Спасибо!

Ответы [ 3 ]

1 голос
/ 15 июня 2009

ОК, я нашел решение, поэтому собираюсь ответить на свой вопрос:

Во-первых, я обнаружил, что с помощью нового прокси-класса в стиле WCF «Справочник по службам» позволяет устанавливать параметры безопасности в файле app.config. Ключ (в моем сценарии) состоит в том, чтобы установить режим только для учетных данных транспорта, указать Windows в качестве типа и указать домен в атрибуте области:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="Service1Soap" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Windows" realm="mydomain.com" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://server.mydomain.com/HelloWorldSvc/Service1.asmx"
                binding="basicHttpBinding" bindingConfiguration="Service1Soap"
                contract="ServiceReference1.Service1Soap" name="Service1Soap" />
        </client>
    </system.serviceModel>

Далее я использовал превосходную оболочку Эрнана де Лахитта для функции API CredUIPromptForCredentials , чтобы запросить у пользователя учетные данные, если возникло исключение безопасности, и сохранить его в их профиле:

ServiceReference1.Service1SoapClient c = new Service1SoapClient();
retry:
try
{
    MessageBox.Show(this, c.HelloWorld());
}
catch (System.ServiceModel.Security.MessageSecurityException securityException)
{
    UserCredentialsDialog creds = new UserCredentialsDialog("*.mydomain.com", "My App",
                                                                        "Enter your enterprise credentials.  Enter your user name as \"MyDomain\\username\"");
    creds.Flags = UserCredentialsDialogFlags.Persist;
    if (creds.ShowDialog() == DialogResult.OK)
    {
        goto retry;
    }
}

c.Close();

Да, это "гото". **** GASP ****:)

1 голос
/ 15 июня 2009

Я не верю, что вы можете использовать их напрямую. Я считаю, что вы должны запросить у пользователя их, а затем, как только пользователь предоставит их, вы можете запросить снова. Вот статья о том, как это сделать . В конце концов, если бы вы могли просто получить учетные данные из DPAPI, это бы победило цель. :)

Вот немного информации. если это поможет ...

Менеджер, содержащий данные в DPAPI, называется Key Manager . Вы можете получить доступ к диспетчеру ключей из пользовательского интерфейса, выполнив start-> run ...

rundll32.exe keymgr.dll, KRShowKeyMgr

Как правило, API для места хранения функций аутентификации: ADVAPI32 . Вы можете найти что-то там, чтобы помочь вам. Вот достойная статья об этом API.

Когда вы добавляете свои учетные данные в CredentialCache, вы также можете попробовать authType "Negotiate" как , описанный здесь .

Извините, это просто исследовательская свалка - я не нашел места для ответа, но, надеюсь, что-то из этого может вам помочь. GL.

0 голосов
/ 15 июня 2009

Я не думаю, что вы можете использовать их в коде, на самом деле ваши единственные варианты:

  1. Жесткое кодирование имени пользователя / pwd, как вы написали (в большинстве случаев большое нет-нет).
  2. Настройка Kerberos с доверием между доменами и компьютерами, чтобы учетная запись домена пользователя могла вызывать службу.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...