如何将(声明)安全令牌传递给启用 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 作为对象传递?