2013-04-26 33 views
2

我正在使用ACS /服務標識作爲臨時STS,同時讓事情到位。不幸的是,雖然我似乎能夠從ACS獲得SAML 1.1令牌,但第二次嘗試將它傳遞給我的WCF服務時,事情變得很瘋狂。據我所知,令牌沒有過期(它正在被快速使用),我不確定它是如何失效的,而且我沒有做過任何關於日誌記錄的信息,這些信息告訴我什麼可能是什麼細節錯誤。我很想將責任歸咎於綁定,因爲我之前從未做過正式的WCF/WIF綁定。任何人都可以看到我使用的客戶端/服務器綁定有任何問題(客戶端是通過服務引用生成的),還是提出了一個可供選擇的調查途徑?使用ACS頒發的令牌和WIF的MessageSecurityException

順便說一句,服務器和客戶端都在同一個開發機器上運行。

的Web.config:

<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="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
    <add key="ida:FederationMetadataLocation" value="--omitted--" /> 
    <add key="ida:ProviderSelection" value="productionSTS" /> 
    </appSettings> 
    <location path="FederationMetadata"> 
    <system.web> 
     <authorization> 
     <allow users="*" /> 
     </authorization> 
    </system.web> 
    </location> 
    <system.web> 
    <compilation debug="true" targetFramework="4.5"> 
     <assemblies> 
     <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 
     </assemblies> 
    </compilation> 
    <httpRuntime targetFramework="4.5" /> 
    </system.web> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <!-- To avoid disclosing metadata information, set the values below to false before deployment --> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="false" /> 
      <serviceCredentials useIdentityConfiguration="true" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <protocolMapping> 
     <add scheme="https" binding="ws2007FederationHttpBinding" /> 
    </protocolMapping> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    <bindings> 
     <ws2007FederationHttpBinding> 
     <binding name=""> 
      <security mode="TransportWithMessageCredential"> 
      <message issuedKeyType="BearerKey" issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"/> 
      </security> 
     </binding> 
     </ws2007FederationHttpBinding> 
    </bindings> 
    </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="true" /> 
    </system.webServer> 
    <system.identityModel> 
    <identityConfiguration> 
     <audienceUris> 
     <add value="https://localhost:44300/Service1.svc" /> 
     </audienceUris> 
     <issuerNameRegistry> 
     <trustedIssuers> 
      <add name="--omitted--" thumbprint="--omitted--"/> 
     </trustedIssuers> 
     </issuerNameRegistry> 
     <certificateValidation certificateValidationMode="None"/> 
    </identityConfiguration> 
    </system.identityModel> 
</configuration> 

App.config中:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="BasicHttpBinding_IService1" /> 
     </basicHttpBinding> 
     <ws2007FederationHttpBinding> 
      <binding name="WS2007FederationHttpBinding_IService1"> 
       <security mode="TransportWithMessageCredential"> 
        <message issuedKeyType="BearerKey" issuedTokenType=""> 
         <tokenRequestParameters> 
          <trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"> 
           <trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</trust:TokenType> 
           <trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType> 
           <trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm> 
           <trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm> 
          </trust:SecondaryParameters> 
         </tokenRequestParameters> 
        </message> 
       </security> 
      </binding> 
     </ws2007FederationHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://localhost:51853/Service1.svc" binding="basicHttpBinding" 
      bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" 
      name="BasicHttpBinding_IService1" /> 
     <endpoint address="https://localhost:44300/Service1.svc" binding="ws2007FederationHttpBinding" 
      bindingConfiguration="WS2007FederationHttpBinding_IService1" 
      contract="ServiceReference1.IService1" name="WS2007FederationHttpBinding_IService1" /> 
    </client> 
    </system.serviceModel> 

客戶機代碼:

static void Main(string[] args) 
    { 
     var factory = new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress("--Azure ACS URL omitted--")); 
     factory.TrustVersion = TrustVersion.WSTrust13; 
     factory.Credentials.UserName.UserName = "--omitted--"; 
     factory.Credentials.UserName.Password = "--omitted--"; 

     var rst = new RequestSecurityToken 
     { 
      RequestType = RequestTypes.Issue, 
      KeyType = KeyTypes.Bearer, 
      AppliesTo = new EndpointReference("https://localhost:44300/Service1.svc") 
     }; 

     SecurityToken token = factory.CreateChannel().Issue(rst); 

     var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential); 
     binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey; 
     binding.Security.Message.EstablishSecurityContext = false; 

     var factory2 = new ChannelFactory<IService1>(binding, new EndpointAddress("https://localhost:44300/Service1.svc")); 
     factory2.Credentials.SupportInteractive = false; 
     factory2.Credentials.UseIdentityConfiguration = true; 

     var proxy = factory2.CreateChannelWithIssuedToken(token); 

     var info = proxy.GetData("testing"); // Exception thrown here 
    } 

例外:

System.ServiceModel.Security.MessageSecurityException was unhandled 
HResult=-2146233087 
Message=An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail. 
Source=mscorlib 
StackTrace: 
    Server stack trace: 
    at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) 
    at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout) 
    at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) 
    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
    at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
    at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 
Exception rethrown at [0]: 
    at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
    at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 
    at TestWCFClient.ServiceReference1.IService1.GetData(String value) 
    at TestWCFClient.Program.Main(String[] args) in c:\Users\nicole\Documents\Visual Studio 2012\Projects\TestWCFClient\Program.cs:line 43 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 
InnerException: System.ServiceModel.FaultException 
    HResult=-2146233087 
    Message=The message could not be processed. This is most likely because the action 'http://tempuri.org/IService1/GetData' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding. 
    InnerException: 

ETA: 此外,我嘗試過:切換到SAML 2.0,使用預覽的JWT令牌處理程序切換到JWT,更改接收超時,將主機時間切換到UTC,將主機與Windows時間服務同步,並在使用令牌之後等待五分鐘。

+0

對我來說,好像你正在調用同一個sts服務兩次(端口44300),而它看起來像第二個應該去51853.讓我知道這是否是一個正確的答案。 – 2013-04-26 18:28:14

+0

第一個請求將進入我的Azure ACS命名空間,即我的臨時STS;我可以理解它可能會讓人困惑的地方。我只需要一個具有與本地主機URL匹配的領域的令牌。它絕對不應該去51853,因爲如果這樣做,我會通過不安全的交通工具發送安全令牌。 – 2013-04-26 18:46:14

+0

我的意思是第二次請求,而不是第一次請求。與工廠2。 – 2013-04-26 18:54:54

回答

1

MessageSecurityException是正確的:這是一個綁定錯誤。

我正在混合一些代碼樣本在一起,並被不匹配咬傷。 EstablishSecurityContext不僅僅是裝飾,它是綁定的一部分,值必須在服務和客戶端之間匹配。

我的應用程序代碼讀取:

var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential); 
    binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey; 
    binding.Security.Message.EstablishSecurityContext = false; // this line is the problem 

服務綁定是:

<bindings> 
    <ws2007FederationHttpBinding> 
    <binding name=""> 
     <security mode="TransportWithMessageCredential"> 
     <message issuedKeyType="BearerKey" issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"/> <!-- this line does not match --> 
     </security> 
    </binding> 
    </ws2007FederationHttpBinding> 
</bindings> 

服務綁定應該是:

<bindings> 
    <ws2007FederationHttpBinding> 
    <binding name=""> 
     <security mode="TransportWithMessageCredential"> 
     <message issuedKeyType="BearerKey" establishSecurityContext="false"/> 
     </security> 
    </binding> 
    </ws2007FederationHttpBinding> 
</bindings> 

而且似的,它的工作原理。

相關問題