<security> 使用 SAML 令牌使用 WCF 和使用联合绑定时的标记要求
<security> tag requirement in consuming WCF with SAML token and using Federation binding
我们有 STS 服务,出于安全原因,它在组织内提供 SAML 令牌,所有应用程序都应获得此令牌。我正在构建一个 WCF 服务,它应该接受 SAML 令牌并在服务请求之前对其进行验证。
到目前为止,我已经设置了联合绑定 [虽然不确定其预期要求,因为我的服务仅服务于防火墙内的 interal/intranet 应用程序。我设法通过使用 SOAP UI 访问了我的 WCF,并在调试时也获得了响应。但是,奇怪的是在我必须在安全标签下屏蔽我的 SAML 的请求中,否则它永远不会工作;我想知道是否有任何变通方法可以解决这个问题,或者这是预期用途。因为 Java 客户端将使用我的 WCF 服务。
<?xml version="1.0" ?>
<configuration>
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.30319.17929, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<appSettings>
<add key="EncryptionCertificateName" value="xxxx" />
<add key="AssertionSignatureCertificateName" value="xxxx" />
<add key="EnablePerformanceLog" value="false" />
<add key="Logging.Level" value="0" />
<add key="Logging.Active" value="True" />
</appSettings>
<runtime>
<gcServer enabled="true" />
<generatePublisherEvidence enabled="false" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<compilation debug="true" targetFramework="4.5" optimizeCompilations="true" batch="true" maxConcurrentCompilations="8" />
<httpRuntime targetFramework="4.5" minFreeThreads="10" minLocalRequestFreeThreads="10" requestValidationMode="2.0" />
</system.web>
<system.net>
<defaultProxy enabled="false">
<proxy usesystemdefault="False" bypassonlocal="True" autoDetect="False" />
</defaultProxy>
<connectionManagement>
<add address="*" maxconnection="5000" />
</connectionManagement>
</system.net>
<system.serviceModel>
<diagnostics performanceCounters="All">
<messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
<endToEndTracing propagateActivity="true" messageFlowTracing="true" />
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceCredentials useIdentityConfiguration="true" />
<serviceAuthorization principalPermissionMode="Always" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<serviceActivations>
<add relativeAddress="Service.svc" service="XX.XXX.BusinessService.Service.VaultService" factory="XX.XXXX.BusinessService.Service.WcfServiceFactory" />
</serviceActivations>
</serviceHostingEnvironment>
<bindings>
<ws2007FederationHttpBinding>
<binding name="ws2007Binding">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false" issuedKeyType="BearerKey" issuedTokenType="urn:oasis:names:tc:SAML:2.0:assertion" negotiateServiceCredential="false" />
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<services>
<service name="XX.XXXX.BusinessService.Service.Service">
<host>
<baseAddresses>
<add baseAddress="https://localhost/XX.XXX.BusinessService.Service/" />
</baseAddresses>
</host>
<endpoint address="" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007Binding" contract="XX.XXXX.Contract.Service.ServiceContract.IService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="false" />
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.identityModel>
<identityConfiguration saveBootstrapContext="true">
<!--<audienceUris>
<add value="VaultService.svc"/>
</audienceUris>-->
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<trustedIssuers>
<add name="XX-XX-XX" thumbprint="XXX" />
</trustedIssuers>
</issuerNameRegistry>
<securityTokenHandlers>
<remove type="System.IdentityModel.Tokens.Saml2SecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<add type="XX.XXX.Extension.Security.MySecurityTokenHandler, XXX.XXX.Extension" />
</securityTokenHandlers>
<claimsAuthenticationManager type="XX.XXXX.Extension.Security.ClaimsAuthenticationManager, XX.XXXX.Extension" />
</identityConfiguration>
</system.identityModel>
<location path="health-check.axd">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<httpErrors existingResponse="PassThrough" />
</system.webServer>
</location>
</configuration>
来自 SOAP 的示例请求 UI:
<soap:Envelope xmlns:soa="http://XXX.com.au/soa" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:ing="http://schemas.datacontract.org/2004/07/XXX.Contract.Vault.DataContract" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/IService1/DoWork</a:Action>
<a:MessageID>urn:uuid:b48f6fa8-f5f2-48d8-a06b-1a202c71ed30</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1"></a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2015-10-26T10:47:54.721Z</u:Created>
<u:Expires>2015-10-26T10:53:54.721Z</u:Expires>
</u:Timestamp>
<Assertion ID="_e058ad04-1d5e-47cf-9fbc-d65aecfaf9ef" IssueInstant="2015-10-24T06:22:37.086Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">...</Assertion>
</o:Security>
</soap:Header>
<soap:Body>
....
.....
</soap:Body>
</soap:Envelope>
你看到这里的 SAML 断言包含在标签下,如果我删除它,服务将无法工作,提示安全消息 header 不存在错误。
这似乎是必需的安全标记,因为我正在为令牌使用联合绑定和身份模型。无论如何 java 服务在将令牌包装在生成安全标记的 generricXMLtoken 中后能够使用该服务。
我们有 STS 服务,出于安全原因,它在组织内提供 SAML 令牌,所有应用程序都应获得此令牌。我正在构建一个 WCF 服务,它应该接受 SAML 令牌并在服务请求之前对其进行验证。
到目前为止,我已经设置了联合绑定 [虽然不确定其预期要求,因为我的服务仅服务于防火墙内的 interal/intranet 应用程序。我设法通过使用 SOAP UI 访问了我的 WCF,并在调试时也获得了响应。但是,奇怪的是在我必须在安全标签下屏蔽我的 SAML 的请求中,否则它永远不会工作;我想知道是否有任何变通方法可以解决这个问题,或者这是预期用途。因为 Java 客户端将使用我的 WCF 服务。
<?xml version="1.0" ?>
<configuration>
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.30319.17929, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<appSettings>
<add key="EncryptionCertificateName" value="xxxx" />
<add key="AssertionSignatureCertificateName" value="xxxx" />
<add key="EnablePerformanceLog" value="false" />
<add key="Logging.Level" value="0" />
<add key="Logging.Active" value="True" />
</appSettings>
<runtime>
<gcServer enabled="true" />
<generatePublisherEvidence enabled="false" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<compilation debug="true" targetFramework="4.5" optimizeCompilations="true" batch="true" maxConcurrentCompilations="8" />
<httpRuntime targetFramework="4.5" minFreeThreads="10" minLocalRequestFreeThreads="10" requestValidationMode="2.0" />
</system.web>
<system.net>
<defaultProxy enabled="false">
<proxy usesystemdefault="False" bypassonlocal="True" autoDetect="False" />
</defaultProxy>
<connectionManagement>
<add address="*" maxconnection="5000" />
</connectionManagement>
</system.net>
<system.serviceModel>
<diagnostics performanceCounters="All">
<messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
<endToEndTracing propagateActivity="true" messageFlowTracing="true" />
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceCredentials useIdentityConfiguration="true" />
<serviceAuthorization principalPermissionMode="Always" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<serviceActivations>
<add relativeAddress="Service.svc" service="XX.XXX.BusinessService.Service.VaultService" factory="XX.XXXX.BusinessService.Service.WcfServiceFactory" />
</serviceActivations>
</serviceHostingEnvironment>
<bindings>
<ws2007FederationHttpBinding>
<binding name="ws2007Binding">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false" issuedKeyType="BearerKey" issuedTokenType="urn:oasis:names:tc:SAML:2.0:assertion" negotiateServiceCredential="false" />
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<services>
<service name="XX.XXXX.BusinessService.Service.Service">
<host>
<baseAddresses>
<add baseAddress="https://localhost/XX.XXX.BusinessService.Service/" />
</baseAddresses>
</host>
<endpoint address="" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007Binding" contract="XX.XXXX.Contract.Service.ServiceContract.IService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="false" />
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.identityModel>
<identityConfiguration saveBootstrapContext="true">
<!--<audienceUris>
<add value="VaultService.svc"/>
</audienceUris>-->
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<trustedIssuers>
<add name="XX-XX-XX" thumbprint="XXX" />
</trustedIssuers>
</issuerNameRegistry>
<securityTokenHandlers>
<remove type="System.IdentityModel.Tokens.Saml2SecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<add type="XX.XXX.Extension.Security.MySecurityTokenHandler, XXX.XXX.Extension" />
</securityTokenHandlers>
<claimsAuthenticationManager type="XX.XXXX.Extension.Security.ClaimsAuthenticationManager, XX.XXXX.Extension" />
</identityConfiguration>
</system.identityModel>
<location path="health-check.axd">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<httpErrors existingResponse="PassThrough" />
</system.webServer>
</location>
</configuration>
来自 SOAP 的示例请求 UI:
<soap:Envelope xmlns:soa="http://XXX.com.au/soa" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:ing="http://schemas.datacontract.org/2004/07/XXX.Contract.Vault.DataContract" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/IService1/DoWork</a:Action>
<a:MessageID>urn:uuid:b48f6fa8-f5f2-48d8-a06b-1a202c71ed30</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1"></a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2015-10-26T10:47:54.721Z</u:Created>
<u:Expires>2015-10-26T10:53:54.721Z</u:Expires>
</u:Timestamp>
<Assertion ID="_e058ad04-1d5e-47cf-9fbc-d65aecfaf9ef" IssueInstant="2015-10-24T06:22:37.086Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">...</Assertion>
</o:Security>
</soap:Header>
<soap:Body>
....
.....
</soap:Body>
</soap:Envelope>
你看到这里的 SAML 断言包含在标签下,如果我删除它,服务将无法工作,提示安全消息 header 不存在错误。
这似乎是必需的安全标记,因为我正在为令牌使用联合绑定和身份模型。无论如何 java 服务在将令牌包装在生成安全标记的 generricXMLtoken 中后能够使用该服务。