Как указать требования к типу претензий на стороне службы, чтобы они выполнялись по запросу клиента? - PullRequest
3 голосов
/ 26 августа 2010

у меня есть:

  • Пассивное STS "приложение для входа", которое также является поставщиком удостоверений.
  • Активная служба WCF STS, которая может принимать и обрабатывать токены ActAs
  • проверяющая сторона веб-сайта
  • проверяющая сторона службы WCF, вызываемая веб-сайтом.

Все это объединено с использованием Windows Identity Foundation и пользовательского кода STS. Active Directory (ADFS) не участвует.

Теперь я работаю:

  1. Пользователь пытается посетить веб-сайт RP.
  2. Пользователь перенаправляется на пассивный STS.
  3. Пользователь входит в систему, получает токен, перенаправляется обратно на веб-сайт RP.
  4. RP веб-сайта выполняет сервисный вызов RPF WCF и передает токен ActAs, чтобы произошло делегирование.
  5. Active STS видит входящий токен ActAs и правильно настраивает выходной идентификатор, поэтому основным идентификатором является токен ActAs, а идентификатор вызывающего абонента добавляется в цепочку акторов.
  6. WCF RP получает правильный токен со всем на месте, у текущего участника потока есть правильная идентификация и утверждения, как и должно быть.

Я хочу, чтобы WCF RP запросил дополнительные заявки от активного STS.

То есть в RST, который идет к активной STS, я хочу, чтобы он включал список утверждений, которые требуются службе, чтобы эти дополнительные утверждения можно было получить, если их еще нет.

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

У меня такое ощущение, что это связано с привязкой, которую я использую. У меня были проблемы с работой ws2007FederationHttpBinding с токенами ActAs, и все примеры в WIF Identity Training Kit использовали customBinding, поэтому я тоже это сделал, и в конце концов это сработало. Вот фрагмент конфигурации из WCF RP, показывающий мою конфигурацию привязки:

<system.serviceModel>
  <bindings>
    <customBinding>
      <binding name="CustomBinding_FederatedService">
        <security
          authenticationMode="IssuedTokenForCertificate"
          messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
          <issuedTokenParameters tokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
            <issuer address="http://localhost:38901/ActiveSts.svc/IWSTrust13" />
            <issuerMetadata address="http://localhost:38901/ActiveSts.svc/mex" />
          </issuedTokenParameters>
        </security>
        <textMessageEncoding>
          <readerQuotas maxArrayLength="32767" />
        </textMessageEncoding>
        <httpTransport />
      </binding>
    </customBinding>
  </bindings>
</system.serviceModel>

Если я изменю конфигурацию на вызывающем веб-сайте, чтобы она указала в элементе ApplicTypeRequirements в разделе Кому выданоТокенПараметры, Active STS действительно видит список требуемых утверждений в RST ... но это на вызывающем веб-сайте, что проблематично для я.

Как мне сделать так, чтобы RP WCF мог указать дополнительные требования, которые ему требуются, без необходимости дублировать эту конфигурацию на вызывающем веб-сайте?

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

1 Ответ

4 голосов
/ 31 августа 2010

Оказывается, ты должен сделать так, чтобы ...

  1. Найдите способ получения требований к претензиям на стороне клиента. Это может быть какая-то служба централизованного конфигурирования, WS-Policy / Metadata Exchange или что угодно.
  2. Вручную создайте запрос токена для STS. Вместо того, чтобы использовать метод расширения Microsoft.IdentityModel CreateChannelActingAs(token), вручную запросите токен ActAs (или новый токен), используя WSTrustChannelFactory.
  3. Добавить запрошенный вручную токен в параметры исходящего канала.

Обратите внимание, что это не совсем устраняет необходимость для вашего клиента знать о требованиях к списку требований, но дает вам возможность каким-то образом централизовать эту конфигурацию или даже использовать сам сервис для предоставления этого списка требований к требованиям. , К сожалению, в стеке Microsoft.IdentityModel нет ничего, что сделало бы все это за вас. Клиенту абсолютно необходимо знать требования к списку требований, поскольку запрос маркера безопасности выдается как часть клиентского взаимодействия, а не выдается службой при поступлении запросов на обслуживание службы.

В любом случае, вы можете увидеть некоторые приличные объяснения WSTrustChannelFactory и WSTrustChannel на веб-сайте MSDN . Мое решение основано на этом.

Выгруженный без обработки ошибок и т. Д., Код в основном выглядит следующим образом:

// You need the channel factory so you can get info about the endpoint.
var factory = new ChannelFactory<IService>();

// Get the issuedTokenParameters information from the binding.
// You see this in the XML config but it's painful to access.
var tokenParameters = factory.Endpoint.Binding
    .CreateBindingElements()
    .OfType<SecurityBindingElement>().First()
    .EndpointSupportingTokenParameters
    .Endorsing.OfType<IssuedSecurityTokenParameters>().First();

// Prepare the RST.
var trustChannelFactory = new WSTrustChannelFactory(tokenParameters.IssuerBinding, tokenParameters.IssuerAddress);
var trustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel();
var rst = new RequestSecurityToken(RequestTypes.Issue);
rst.AppliesTo = factory.Endpoint.Address;

// If you're doing delegation, set the ActAs value.
var principal = Thread.CurrentPrincipal as IClaimsPrincipal;
var bootstrapToken = principal.Identities[0].BootstrapToken;
rst.ActAs = new SecurityTokenElement(bootstrapToken);

// Here's where you can look up claims requirements dynamically.
rst.Claims.Add(new RequestClaim("http://dynamically-added-claim"));

// Get the token and attach it to the channel before making a request.
RequestSecurityTokenResponse rstr = null;
var issuedToken = trustChannel.Issue(rst, out rstr);
var fccParameters = new FederatedClientCredentialsParameters();
fccParameters.IssuedSecurityToken = issuedToken;
var channel = factory.CreateChannel();
((IChannel)channel).GetProperty<ChannelParameterCollection>().Add(fccParameters);

// NOW you can make the request.
channel.DoWork();

Это также позволяет вам кэшировать выданный токен, если вы хотите оптимизировать некоторые коммуникации, протекающие по системе.

Конечно, если вы не пытаетесь динамически вставить требования претензии или если вы по-другому довольны использованием конфигурации XML и дублированием ее на сервере и на клиенте, в этом нет необходимости. Метод расширения CreateChannelActingAs(token) и весь стек Microsoft.IdentityModel позаботятся об этом за вас.

...