如何将(声明)安全令牌传递给启用 WIF 的 WCF 服务?

Posted

技术标签:

【中文标题】如何将(声明)安全令牌传递给启用 WIF 的 WCF 服务?【英文标题】:How do you pass a (Claims) security Token to a WIF enabled WCF service? 【发布时间】:2013-07-02 15:32:41 【问题描述】:

我的望远镜:

实现安全asp mvc(ok)

在 wcf 中实现安全性(不行)

将令牌从客户端传递给 wcf。(不好)

我的代码客户端

    using System.IdentityModel.Tokens;
    using System.Security.Claims;
    using System.ServiceModel;
    using System.ServiceModel.Security;
    using System.Web.Mvc;
    using Microsoft.IdentityModel.Protocols.WSTrust;
    using Nobre.Core.Helpers;
    using Wcf;


    namespace Mvc.Controllers
    
        public class HomeController : Controller
        
            [Authorize]
            public ActionResult Index()
            
                var identity = HttpContext.User.Identity as ClaimsIdentity;
                var securityToken = WcfHelper.GetActAsToken(identity.BootstrapContext as BootstrapContext);
                var serviceAddress = "https://estnbr363.nobre.local/Service1.svc";
                var binding = new WSFederationHttpBinding();

                binding.Security.Mode = WSFederationHttpSecurityMode.TransportWithMessageCredential;
                binding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Basic256Rsa15;
                binding.Security.Message.NegotiateServiceCredential = true;
                binding.Security.Message.IssuedKeyType = SecurityKeyType.SymmetricKey;
                binding.Security.Message.IssuedTokenType ="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#samlv1.1";

                var factory = new ChannelFactory<IService1>(binding, serviceAddress);
                factory.ConfigureChannelFactory();
                factory.Credentials.SupportInteractive = false;
                var channel = factory.CreateChannelActingAs(securityToken);  

                return View( channel.GetData(1));

            
        
    


    web config service         
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
  </configSections>
  <appSettings>
    <add key="ida:FederationMetadataLocation" value="https://nobre-security.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml" />
    <add key="ida:Issuer" value="https://nobre-security.accesscontrol.windows.net/v2/wsfederation" />
    <add key="ida:ProviderSelection" value="ACS" />
  </appSettings>
  <location path="FederationMetadata">
    <system.web>
      <!--<authorization>
        <allow users="*" />
      </authorization>-->
    </system.web>
  </location>
  <system.web>
    <!--<authorization>
      <deny users="?" />
    </authorization>-->
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.serviceModel>
    <diagnostics>
      <messageLogging maxMessagesToLog="25000" logEntireMessage="true" logMessagesAtServiceLevel="false"  logMalformedMessages="true" logMessagesAtTransportLevel="true">
        <filters>
          <clear/>
        </filters>
      </messageLogging>
    </diagnostics>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials useIdentityConfiguration="true" />
          <serviceAuthorization principalPermissionMode="Always" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <bindings>
      <ws2007FederationHttpBinding >
        <binding >
          <security mode="TransportWithMessageCredential">
            <message  issuedKeyType="BearerKey" negotiateServiceCredential="true">
              <issuerMetadata address="https://federation.nobre.net.br/adfs/services/trust/mex" />
            </message>
          </security>
        </binding>
      </ws2007FederationHttpBinding>
    </bindings>
    <services>
      <service name="Wcf.Service1" behaviorConfiguration="">
        <endpoint name="ws2007FederationHttpBinding.Service1" address="ws2007FederationHttpBinding" binding="ws2007FederationHttpBinding" contract="Wcf.IService1" />
      </service>    
    </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <directoryBrowse enabled="true" />
  </system.webServer>
  <system.identityModel>
    <identityConfiguration saveBootstrapContext="true">
      <audienceUris>
        <add value="https://estnbr363.nobre.local/Service1.svc" />
      </audienceUris>
      <issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
        <authority name="https://nobre-security.accesscontrol.windows.net/">
          <keys>
            <add thumbprint="213D414F8E89D865FD10A49C8C8F838A9460EBEE" />
          </keys>
          <validIssuers>
            <add name="https://nobre-security.accesscontrol.windows.net/" />
          </validIssuers>
        </authority>
      </issuerNameRegistry>      
      <certificateValidation certificateValidationMode="None" />
    </identityConfiguration>
  </system.identityModel>  
</configuration>

线路错误

channel.GetData(1);

未指定安全令牌发行者的地址。必须在指向“https://estnbr363.nobre.local/Service1.svc”目标的链接上指定明确的发件人地址,或者必须在凭据中配置发件人的地址位置。

the problem are these lines below! how to implement ?

  // Extract the STS certificate from the certificate store. ?????????
      X509Store store = new X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser);
      store.Open(OpenFlags.ReadOnly);
      X509Certificate2Collection certs = store.Certificates.Find(
          X509FindType.FindByThumbprint, "0000000000000000000000000000000000000000", false);
      store.Close();

      // Create an EndpointIdentity from the STS certificate. ???????????
      EndpointIdentity identity = EndpointIdentity.CreateX509CertificateIdentity ( certs[0] );

      // Set the IssuerAddress using the address of the STS and the previously created ???????

      // EndpointIdentity.
      b.Security.Message.IssuerAddress = 
          new EndpointAddress(new Uri("http://localhost:8000/sts/x509"), identity);

【问题讨论】:

【参考方案1】:

我也遇到过类似的问题

factory.Credentials.SupportInteractive = false;

为我关闭了 CardSpace。只需将其放在客户端代码中的ConfigureChannelFactory() 之后即可。

[Authorize]
public ActionResult Index()
    var identity = HttpContext.User.Identity as ClaimsIdentity;
    var securityToken = WcfHelper.GetActAsToken(identity.BootstrapContext as BootstrapContext);   
    string serviceAddress = "svc";
    var binding = new     WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
    var factory = new ChannelFactory<IService>(binding,new EndpointAddress(serviceAddress));
    factory.ConfigureChannelFactory();
    factory.Credentials.SupportInteractive = false;
    var channel = factory.CreateChannelActingAs(securityToken);
    channel.DoWork();

SupportInterative:

获取或设置一个值,该值指示系统是否允许 必要时以交互方式提示用户输入凭据。为了 例如,在中间层可能需要将其设置为 false 场景。

【讨论】:

channel.DoWork();错误 未指定安全令牌发行者的地址。必须在指向“estnbr363.nobre.local/Service1.svc”目标的链接上指定明确的颁发者地址,或者必须在凭据中配置发件人的地址位置。 那是一个完全不同的问题。在此处查看接受的答案:***.com/questions/7716218/… 您应该考虑配置一个 mex 端点并让 Visual Studio 为您生成服务引用。如果您想在代码中创建端点,您必须非常仔细地查看绑定。您缺少有关安全配置的所有内容。看看这里:msdn.microsoft.com/de-de/library/… 感谢您的帮助,但错误仍然存​​在。我把代码贴在上面了,你能帮帮我吗?

以上是关于如何将(声明)安全令牌传递给启用 WIF 的 WCF 服务?的主要内容,如果未能解决你的问题,请参考以下文章

如何将接收到的(承载)访问令牌传递给生成的 REST 客户端,以调用安全的 API-Gateway 端点

如何使用 Payflow 将 securitytokenid 作为对象传递?

WIF 通过 AJAX 到一个单独的域

如何将 Cognito 令牌传递给 Amazon API Gateway?

如何将身份验证令牌传递给端点?

如何在声明未映射到 AD 帐户的情况下执行 WIF/声明模拟?