ADFS throws request too long error

4,334 views
Skip to first unread message

Thinh Nguyen

unread,
Jul 8, 2016, 5:30:55 AM7/8/16
to pac4j-users
I don't understand the certs stuff really well... I've managed to get the SAML working with ADFS on our local environment. We created a keystore using keytool, we exported the public cert and gave it to ADFS team, they imported it and then it's working fine..

However, for our production environment, we can't use a self-signed cert using keytool, so we exported the .csr from the key store, gave it to the security team, they signed it, we then imported it into our keystore. And when we imported, we needed to import the root, the intermediate and then the cert. The same certs are given to the ADFS team to import.. So in theory it should work.

However, whenever we attempted to talk to ADFS it's complaining about the request is too long... and by looking at the request, it sent all the chain in the payload... and I suspected this caused the request too long..

So I am wondering if there is a way that we could only send the cert instead of the whole chain? is that the right thing to do? do you have any suggestions?

Thanks & regards
Thinh

Jaroslav Kačer

unread,
Jul 8, 2016, 5:06:21 PM7/8/16
to pac4j-users
Hi Thinh!

I remember I tried to achieve the same thing some time ago but didn't succeed. I also imported the root certificate and the intermediary certificate into their respective stores on the ADFS server but it didn't work. I used EJBCA to manage the certificates. Now I don't remember what error I was getting on the ADFS side but I wouldn't say it was related to request length.

I encountered the "Request too long" error on a different occasion. A few users of a partner company were getting 400 - Bad Request responses from ADFS, saying "Request too long". It turned out this was caused by extremely long cookie values issued by IIS during authentication. IIS has a limit on request length; by default the limit is set to 16 KB. If a request is longer, it is rejected. You can change the value in the IIS management console. Try to capture your requests with a proxy (Fiddler, BurpSuite, ...) and measure its length. Is is longer than 16 KB? If it is, try to adjust the limit and try again. I can send a link to MS Knowledge Base if you need it.

Overall, I'm not sure that the approach with certificate chains is the right one for SAML. I understand it for HTTP communication where you access many different servers and it would be painful to express trust individually to each of them. For SAML, you must import the other party's metadata with the certificate, which in fact means you express your trust to the other party. Is there any benefit of a CA-signed certificate over a self-signed one here?  I wasn't able to find any answer to this question. What are the arguments of your ADFS team on this?

Best Regards,
   Jarda

Thinh Nguyen

unread,
Jul 8, 2016, 7:32:20 PM7/8/16
to pac4j-users
Thank you Jarda,

I was thinking exactly the same about self-signed cert is no different to signed-cert...I'll have a chat with the ADFS team next week.

Are you referring to the request with the entire content (to get the request size) ? e.g

<saml2p:AuthnRequest 
 ...everything in here?
</saml2p:AuthnRequest>
 

Regards
Thinh?

Jaroslav Kačer

unread,
Jul 11, 2016, 4:10:30 AM7/11/16
to pac4j-users
Hi Thinh!

I have looked up the details of the error. It seems the limit does not apply to the whole request but to every single HTTP header. All cookies come in a single header, so a few "longer" cookies can cause the error.

Here are some relevant links to the MS Knowledge Base:

In my case, the cookies and their lengths were:
SamlSession                                           419
MSISSignOut                                            83
MSISAuthenticated                                      49
MSISLoopDetectionCookie                                54
MSISSamlRequest                                      2019
MSISSamlRequest1                                     2020
MSISSamlRequest2                                     1645
MSISContext59e5cee1-c83d-4f55-ae1c-8af4c8b2440a      2051
MSISContext59e5cee1-c83d-4f55-ae1c-8af4c8b2440a1     2052
MSISContext59e5cee1-c83d-4f55-ae1c-8af4c8b2440a2     1732
MSISTtpDataReceivedCookie                              85
MSISIPSelectionSession                                 78
MSISContext3febe5ed-4f86-40f5-ab7b-3cc1d0351755      2051
MSISContext3febe5ed-4f86-40f5-ab7b-3cc1d03517551     2052
MSISContext3febe5ed-4f86-40f5-ab7b-3cc1d03517552     1732
ASP.NET_SessionId                                      45
.VISFedAuth                                           495
.VISFedAuthBasic                                      500
SMSESSION                                            1209
LtpaToken2                                            846
LtpaToken                                             421

Here you can see that either IIS or ADFS creates several copies of the same cookie (already quite long) which causes the limit to be exceeded.

ADFS uses a few redirects during authentication, so even if the original request from your application does not have these cookies, they can appear after the first redirect. Unfortunately I have no idea if this behavior can be somehow controlled or not.

Please examine your users' requests if such cookies are present there or not.

Best Regards,
   Jarda


Dne sobota 9. července 2016 1:32:20 UTC+2 Thinh Nguyen napsal(a):

Thinh Nguyen

unread,
Jul 13, 2016, 3:48:54 AM7/13/16
to pac4j-users
Hi all,

Hi,

I finally figured it out... it seems like AD FS does not require the certs to be in its payload request. And the library has no way for us to turn it off..
It's this block of code that set authnRequestSigned to be true when there is a credential provider... 
@Override
public final MetadataResolver resolve() {
try {
final SAML2MetadataGenerator metadataGenerator = new SAML2MetadataGenerator();
if (this.credentialProvider != null) {
metadataGenerator.setCredentialProvider(this.credentialProvider);
metadataGenerator.setAuthnRequestSigned(true);
}
....
}

So I overrode the SamlClient to pass in a null credentialProvider to stop the authRequestSigned being set to true. 
The payload now looks like this
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                     AssertionConsumerServiceURL="https://host/callback?client_name=MySamlClient"
                     Destination="https://destination/adfs/ls/"
                     ForceAuthn="false"
                     ID="_ucxkt7kyvp5x2lzfkkcbw65plrul393mmm2iqth"
                     IsPassive="false"
                     IssueInstant="2016-07-12T08:27:14.778Z"
                     ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                     ProviderName="pac4j-saml"
                     Version="2.0"
                     >
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://host</saml2:Issuer>
</saml2p:AuthnRequest>

This worked.. so I am wondering if we could make authnRequestSigned configurable?


Jérôme LELEU

unread,
Jul 13, 2016, 6:56:41 AM7/13/16
to Thinh Nguyen, pac4j-users
Hi,

It might be a silly question, but does it make sense to have a credentials provider and not sign the auth requests at the same time?

I see a authnRequestSigned parameter in the SAML2MetadataGenerator as well.

Would you mind submitting some pull request for that on Github?

Thanks.
Best regards,
Jérôme


--
You received this message because you are subscribed to the Google Groups "pac4j-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages