title: HTTP Status 401 - Authentication Failed: Error decoding incoming SAML message
body: <p>I did everything as described in <a href="http://docs.spring.io/spring-security-saml/docs/1.0.0.RELEASE/reference/html/chapter-quick-start.html" rel="nofollow noreferrer">spring saml tutorial</a>, except that I add   </p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;xml-apis&lt;/groupId&gt;
      &lt;artifactId&gt;xml-apis&lt;/artifactId&gt;
      &lt;version&gt;1.4.01&lt;/version&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>in pom.xml to overcome a w3.dom class not found problem.  When I run the sample project, I got 
  <code>HTTP Status 401 - Authentication Failed: Error decoding incoming SAML message</code> in browser, and at the same time <code>(CertPathPKIXTrustEvaluator.java:81) ERROR org.springframework.security.saml.trust.MetadataCredentialResolver - PKIX path construction failed for untrusted credential: [subjectName='CN=idp.ssocircle.com' |credential entityID='https://idp.ssocircle.com']: unable to find valid certification path to requested target</code> in console. </p>
  
  <p>A package flow screen shot:
  <a href="https://i.stack.imgur.com/YC4d1.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YC4d1.png" alt="package flow screenshot"></a></p>
  
  <p><strong>DAY 2</strong>:
  I ran <code>keytool -importcert -alias identtrustca -file ca.cer -keystore samlKeystore.jks</code> and replace <code>security/samlKeystore.jks</code> with the new generated one. The <code>securityContext.xml</code>:</p>
  
  <pre><code>&lt;bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager"&gt;
      &lt;constructor-arg value="classpath:security/samlKeystore.jks"/&gt;
      &lt;constructor-arg type="java.lang.String" value="nalle123"/&gt;
      &lt;constructor-arg&gt;
          &lt;map&gt;
              &lt;entry key="apollo" value="nalle123"/&gt;
          &lt;/map&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg type="java.lang.String" value="apollo"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>Then I have:</p>
  
  <pre><code>Caused by: java.io.IOException: Keystore was tampered with, or password was incorrect
      at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)
      at sun.security.provider.JavaKeyStore$JKS.engineLoad(Unknown Source)
      at java.security.KeyStore.load(Unknown Source)
      at org.springframework.security.saml.key.JKSKeyManager.initialize(JKSKeyManager.java:117)
      ... 57 more
  Caused by: java.security.UnrecoverableKeyException: Password verification failed
      ... 61 more
  </code></pre>
  
  <p>Then I change the password with the one I entered when use <code>keytool</code>:</p>
  
  <pre><code>&lt;bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager"&gt;
      &lt;constructor-arg value="classpath:security/samlKeystore.jks"/&gt;
      &lt;constructor-arg type="java.lang.String" value="123456"/&gt;
      &lt;constructor-arg&gt;
          &lt;map&gt;
              &lt;entry key="apollo" value="123456"/&gt;
          &lt;/map&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg type="java.lang.String" value="apollo"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>Then console says:</p>
  
  <pre><code>Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
  java.lang.RuntimeException: Key for alias apollo not found
      at org.springframework.security.saml.metadata.MetadataGenerator.getServerKeyInfo(MetadataGenerator.java:201)
  </code></pre>
  
  <p>So I change <code>apollo</code> to <code>identtrustca</code>:</p>
  
  <pre><code>&lt;bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager"&gt;
      &lt;constructor-arg value="classpath:security/samlKeystore.jks"/&gt;
      &lt;constructor-arg type="java.lang.String" value="123456"/&gt;
      &lt;constructor-arg&gt;
          &lt;map&gt;
              &lt;entry key="identtrustca" value="123456"/&gt;
          &lt;/map&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg type="java.lang.String" value="identtrustca"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>and console says:</p>
  
  <pre><code>Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
  java.lang.UnsupportedOperationException: trusted certificate entries are not password-protected
  </code></pre>
  
  <p>Then I read <a href="https://stackoverflow.com/questions/26164109/trusted-certificate-entries-are-not-password-protected-spring-saml">this</a> and <a href="https://stackoverflow.com/questions/33369965/trusted-certificate-entries-are-not-password-protected-java">this</a>, so I delete the entry element (I believe it is the private key stuff), it becomes:</p>
  
  <pre><code>&lt;bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager"&gt;
      &lt;constructor-arg value="classpath:security/samlKeystore.jks"/&gt;
      &lt;constructor-arg type="java.lang.String" value="123456"/&gt;
      &lt;constructor-arg&gt;
          &lt;map/&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg type="java.lang.String" value="identtrustca"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>Now problem becomes:</p>
  
  <pre><code>Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
  java.lang.RuntimeException: Key with alias identtrustca doesn't have a private key
  </code></pre>
  
  <p><strong>DAY 2 2nd part</strong>:
  Now I understand that instead of creating a new keystore I should just use the old samlKeystore.jks. And if using <code>keytool -list -V -keystore d:\temp\samlKeystore.jks</code> one can see it contains 3 items (originally it has 2).</p>
  
  <p>I don't understand why SP gets public key from IdP metadata, but still needs IdP's ca.cer? I believe the ca.cer from the auth website is IdP's certificate, although it is different from the one I get by <code>openssl s_client -connect idp.ssocircle.com:443 -showcerts</code></p>
  
  <p>Moreover, now instead of getting <code>Error decoding incoming SAML message</code>, Now I am having <code>HTTP Status 401 - Authentication Failed: Response issue time is either too old or with date in the future</code></p>
  
  <p><strong>DAY 3</strong>
  When I start SP, visiting <a href="http://localhost:8080/spring-security-saml2-sample/" rel="nofollow noreferrer">http://localhost:8080/spring-security-saml2-sample/</a> from both chrome and firefox, when I pressed global logout in one explorer, and refresh the other one, it does not show a log out page. I thought for SSO, global logout from the same SP should ignore multi-session, e.g., once I global logout in one "login", and I should automatically log out in the other one, I should see a log-out-page in the other explorer too (if I refresh). Actually, for multiple SPs, one I logout in one, I should be able to see logout in all SPs that I once logged in.</p>
  
  <p><strong>DAY n</strong>
  By changing the saml project url, one needs to modify metadata in idp.ssocircle.com (manage metadata). Otherwise, the idp website would show error. This is written in docs/reference/htmlsingle/index.html</p>