2012-05-29 191 views
1

我目前正在研究一個小型ASP.NET項目,涉及針對第三方身份提供者的用戶身份驗證。我在SP發起的SLO請求方面遇到問題。saml令牌解析器無法解析令牌引用

我正在使用WIF SAML 2.0 extension來處理SAML協議。

調試時我的應用程序立即崩潰,給我下面的錯誤信息(我刪除RAWDATA的,所使用的x509證書的公鑰對簽名值):

The token resolver is unable to resolve the token reference 'SecurityKeyIdentifier 
    (
    IsReadOnly = False, 
    Count = 1, 
    Clause[0] = X509RawDataKeyIdentifierClause(RawData =) 
    ) 
'. 

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: The token resolver is unable to resolve the token reference 'SecurityKeyIdentifier 
    (
    IsReadOnly = False, 
    Count = 1, 
    Clause[0] = X509RawDataKeyIdentifierClause(RawData =) 
    ) 
'. 

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Stack Trace: 


[InvalidOperationException: The token resolver is unable to resolve the token reference 'SecurityKeyIdentifier 
    (
    IsReadOnly = False, 
    Count = 1, 
    Clause[0] = X509RawDataKeyIdentifierClause(RawData =) 
    ) 
'.] 
    System.IdentityModel.Selectors.SecurityTokenResolver.ResolveToken(SecurityKeyIdentifier keyIdentifier) +226933 
    Microsoft.IdentityModel.Web.Saml2AuthenticationModule.ReadSelfMetadata(Stream stream, String fileName, String& entityId, EndpointConfiguration& endpointConfiguration, Boolean& signAuthenticationRequests, X509Certificate2& signingCertificate) +771 

[ConfigurationErrorsException: ID4451: The signing key specified in metadata could not be found. Update the key identifier in metadata or ensure the key is present in the ServiceTokenResolver. See the inner exception for more details.] 
    Microsoft.IdentityModel.Web.Saml2AuthenticationModule.ReadSelfMetadata(Stream stream, String fileName, String& entityId, EndpointConfiguration& endpointConfiguration, Boolean& signAuthenticationRequests, X509Certificate2& signingCertificate) +940 
    Microsoft.IdentityModel.Web.Saml2AuthenticationModule..ctor() +606 

[TargetInvocationException: Exception has been thrown by the target of an invocation.] 
    System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0 
    System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98 
    System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241 
    System.Activator.CreateInstance(Type type, Boolean nonPublic) +69 
    System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) +1136 
    System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) +111 
    System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) +23 
    System.Web.HttpRuntime.CreateNonPublicInstance(Type type, Object[] args) +60 
    System.Web.HttpApplication.BuildIntegratedModuleCollection(List`1 moduleList) +231 
    System.Web.HttpApplication.GetModuleCollection(IntPtr appContext) +1365 
    System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +95 
    System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +194 
    System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +339 
    System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +253 

[HttpException (0x80004005): Exception has been thrown by the target of an invocation.] 
    System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +9090876 
    System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97 
    System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +256 

我的SP元如下:

<md:EntityDescriptor 
    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" 
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
    entityID="urn:mace:feide.no:services:no.ntnu.test_lesesalplass"> 

<!--Find where to turn off LogOutRequestSigning!--> 
    <md:SPSSODescriptor 
    WantAssertionsSigned="false" 
    AuthnRequestsSigned="false" 
    protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> 

    <md:KeyDescriptor use="signing"> 
     <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
     <ds:X509Data> 
      <ds:X509Certificate> 
      [...] 
      </ds:X509Certificate> 
     </ds:X509Data> 
     </ds:KeyInfo> 
    </md:KeyDescriptor> 

    <md:KeyDescriptor use="encryption"> 
     <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
     <ds:X509Data> 
      <ds:X509Certificate> 
      [...] 
      </ds:X509Certificate> 
     </ds:X509Data> 
     </ds:KeyInfo> 
    </md:KeyDescriptor> 

    <md:NameIDFormat> 
     urn:oasis:names:tc:SAML:2.0:nameid-format:transient 
    </md:NameIDFormat> 

    <md:SingleLogoutService 
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" 
     Location="http://localhost:52681/LeseSalReg/saml/redirect/slo" 
     ResponseLocation="http://localhost:52681/LeseSalReg/saml/redirect/sloresponse" 
     /> 

    <md:AssertionConsumerService 
     isDefault="true" index="0" 
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" 
     Location="http://localhost:52681/LeseSalReg/saml/post/ac" 
     /> 

    </md:SPSSODescriptor> 
</md:EntityDescriptor> 

我的web.config如下所示:

<?xml version="1.0"?> 

<configuration> 

    <configSections> 
    <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
    <section name="microsoft.identityModel.saml" type="Microsoft.IdentityModel.Web.Configuration.MicrosoftIdentityModelSamlSection, Microsoft.IdentityModel.Protocols"/> 
    </configSections> 

    <connectionStrings> 
    <add name="ApplicationServices" 
     connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true" 
     providerName="System.Data.SqlClient" /> 
    <add name="StudySpaceRegEntities" 
     connectionString="metadata=res://*/LeseSalRegEntity.csdl|res://*/LeseSalRegEntity.ssdl|res://*/LeseSalRegEntity.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=MATSHO;initial catalog=StudySpaceReg;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;" 
     providerName="System.Data.EntityClient" /> 
    </connectionStrings> 

    <system.web> 

    <compilation debug="true" targetFramework="4.0" > 
     <assemblies> 
     <add assembly="Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     </assemblies> 
    </compilation> 

    <siteMap enabled="false"> 
     <providers> 
     <clear/> 
     <add name="AspNetXmlSiteMapProvider" type="System.Web.XmlSiteMapProvider" siteMapFile="Web.sitemap" securityTrimmingEnabled="true" /> 
     </providers> 
    </siteMap> 

    <authentication mode="Forms"> 
     <forms loginUrl="~/About.aspx" timeout="2880" defaultUrl="~/Register.aspx" /> 
    </authentication> 

    <pages controlRenderingCompatibilityVersion="4.0" clientIDMode="AutoID" masterPageFile="~/Site.Master"/> 

    <membership> 
     <providers> 
     <clear/> 
     <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" 
      enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" 
      maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" 
      applicationName="/" /> 
     </providers> 
    </membership> 

    <profile> 
     <providers> 
     <clear/> 
     <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/> 
     </providers> 
    </profile> 

    <roleManager enabled="false"> 
     <providers> 
     <clear/> 
     <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" /> 
     <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" /> 
     </providers> 
    </roleManager> 

    <httpModules> 
     <add name="Saml2AuthenticationModule" type="Microsoft.IdentityModel.Web.Saml2AuthenticationModule"/> 
     <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule"/> 
    </httpModules> 
    </system.web> 

    <system.webServer> 

    <validation validateIntegratedModeConfiguration="false"/> 
    <modules> 
     <add name="Saml2AuthenticationModule" type="Microsoft.IdentityModel.Web.Saml2AuthenticationModule"/> 
     <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule"/> 
    </modules> 

    </system.webServer> 

    <microsoft.identityModel> 
    <service> 

     <audienceUris> 
     <clear/> 
     <add value="urn:mace:feide.no:services:no.ntnu.test_lesesalplass"/> 
     </audienceUris> 

     <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry"> 
     <trustedIssuers> 
      <add name="https://idp-test.feide.no" thumbprint="fa982efdb69f26e8073c8f815a82a0c5885960a2"/> 
     </trustedIssuers> 
     </issuerNameRegistry> 

     <securityTokenHandlers> 
     <remove type="Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
     <add type="Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 

     <remove type="Microsoft.IdentityModel.Tokens.X509SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add type="Microsoft.IdentityModel.Tokens.X509SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 

     <securityTokenHandlerConfiguration saveBootstrapTokens="true" > 
      <audienceUris mode="Always" /> 
     </securityTokenHandlerConfiguration> 
     </securityTokenHandlers> 
    </service> 
    </microsoft.identityModel> 

    <microsoft.identityModel.saml metadata="App_Data\SPmeta.xml"> 
    <identityProviders> 
     <metadata file="App_Data\IdPmeta.xml"/> 
    </identityProviders> 
    </microsoft.identityModel.saml> 

如果我註釋掉KeyDescriptor在SP元數據的簽名證書,應用程序不會崩潰。但是,當我嘗試註銷時,我收到以下例外情況:

ID4450:類型爲「LogoutRequest」的消息在發送之前必須進行簽名。設置消息的SigningCredentials屬性,或者使用非空X509Certificate2配置Saml2MessageDecorator。

我不認爲WIF支持未簽署的SLO請求,所以我必須簽署它們。由於我無法理解的原因,似乎SecurityTokenResolver無法解析用於在元數據中定義的簽名的X509Certificate。

任何指針將深受讚賞。

+0

也許等一個小時,然後將解決方案作爲實際答案發布? – BoltClock

回答

1

解決它:
的問題是因爲證書是如何工作的認識不足朵朵:我試圖使用相同的X509證書籤署雙方IDP和SP的消息。

created a X509Certificate並把它放在我的電腦的「個人商店」。下面的變化做是爲了在web.config:

<microsoft.identityModel> 
    <service> 

     <serviceCertificate> 
     <certificateReference 
      storeName="My" 
      x509FindType="FindByThumbprint" 
      storeLocation="LocalMachine" 
      findValue="82581cf4710c951d0f2e89e97c3a41d2b4a18890" 
     /> 
    </serviceCertificate> 
[...] 

證書的Base64編碼的版本放在SP-元數據。 SecurityTokenHandler然後能夠簽署我的LogoutRequests。