Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

« Previous Version 7 Next »

Generally the Developer has little control over the setup of the Server and Network. Operations configures all of the network devices, the operating system, and even the Tomcat server. However, configuration problems can cause test failures, and the only way to fix these issues is to get the configuration fixed. Generally you only have to review this material when there is a major change to the network or server setup.

SAML Messages

The most important part of any Shibboleth login to an application occurs as it generates a "SAML Response" XML message and sends it to the Service Provider. The message contains a large amount of XML boiler plate and a very small amount of important content.

A lot of Shibboleth testing involves checking the SAML Response to make sure it has the right data for the Subject and for each supplied Attribute. This is determined by the configuration files for Shibboleth. It must find the EntityID of the Service Provider in a configured Metadata file, find the necessarily attributes released in the attribute-filter xml file, generate the SAML Response, and send it to the configured "ACS" URL in the Metadata. The Service Provider will accept the message if the EntityID and digital signature of the Shibboleth server match what it has been configured to expect.

However, Shibboleth passes data back to the Browser in response to something the Browser set to it, and the subsequent transmission of the Response from the Browser to the Service Provider is unrelated to the network configuration of the Shibboleth servers. There is almost nothing in this part of the transmission to configure or test.

IdP Initiated Login

An "IdP Initiated" test occurs when you click a URL that points to our Shibboleth server and provides the EntityID of one of our Service Provider partners:

http://localhost:8080/idp/profile/SAML2/Unsolicited/SSO?providerId=nobody.yale.edu

The hostname part ("localhost:8080") could reference a Sandbox test Shibboleth running on Tomcat on your desktop, or it could be a test version of Shibboleth running on a VM in the machine room where you have created an SSH tunnel connecting port 8080 on your desktop to the real Server port on the real Server VM.

At the end, after "providerId=" you add the EntityID of a partner. It is a Yale testing convention that the ID "nobody.yale.edu" is configured to release a very large number of attributes including most of the interesting ones you might want to check. It is the first test to make because is does so much it will point out most errors.

The Shibboleth code that processes an "Unsolicited/SSO" does not do any network validity checking. It doesn't care what the protocol (http or https), hostname, or port number are. However, during the processing it does Redirect the Browser to a different URL on the same Shibboleth server, and it order to do that it needs to figure out what its own URL actually is from the point of view of the Browser.

Shibboleth is running on some VM in the machine room. You could be accessing it through the public production URL ("https://auth.yale.edu/idp") but you could also have set up an SSH tunnel from your local computer port 8080 to the VM port 8080 (the port Tomcat uses). The problem is that Tomcat and Shibboleth cannot tell from the network protocol just how the network traffic is routed between the Browser and the VM. The only hint it has is the HTTP Host Header.

Initially the Browser will have generated a Host header based on the network address in the URL it started with. In these cases, the header will either be "http://localhost:8080" or else "https://auth.yale.edu". The Host header may pass through a number of intermediate devices, and some of them may edit some of the HTTP content, but the meaning of the Host header as "the network address of the server from the point of view of the Browser" should be preserved. Then when Shibboleth needs to Redirect the Browser from one of its URLs to another URL, it can use the Host header as the start of the Redirect URL and know that when the Browser can use it to get back to the same Shibboleth server.

If you submit an IdP Initiated Login to Shibboleth and immediately get a Browser redirect to a completely different URL location, then someone has messed up the Host header between the Browser and Shib.

There is a different Redirect problem when Shibboleth uses CAS to log you in. The convention with CAS is that Shib, like any other CAS client, provides a service= string that contains a URL in the Tomcat server to which CAS can Redirect the Browser after it has added the Service Ticket ID. For some reason, although the Unicon CAS-Shib itegration code has access to the Host header, it only uses that header to set the port number. The rest of the Service URL is constructed from a property that in the Yale Install Project is called "cas.target.url" and is supplied at install time.

The problem is that this property is not dynamic and it is not going to adjust between "localhost:8080" for an SSH tunnel and "auth.yale.edu" through the F5. Since it seems like a very bad practice to configure the VM with properties that will not work in production, if you discover that Shibboleth is Redirecting the Browser to CAS with a Service URL that cannot possibly get back to the Shib VM in the way you are currently accessing that VM, then you have to use one of the Client configuration tools described in the Client Configuration part of this set of documents to rewrite or reroute the Service URL (the Browser Redirector plugin can do it for example).

The IdP Initated Login provides the simplest set of tests. About 95% or more of Service Providers will accept IdP Initiated, and you should do all that testing first. It is also the simplest network setup because you only have to fix the two Redirect problems (Shib to Shib and CAS to Shib) if they happen to occur.

In fact, for initial testing it is not actually necessary for the SAML Response to be delivered to the Service Provider (or for it to be trusted if it does arrive there). If you are running the SAML Tracer in Firefox you can capture the SAML Response and usually determine if the Subject and Attributes are correct just by inspecting it.

However, for final 100% coverage testing, then you should use production credentials to generate a SAML Response the Service Provider will actually accept and log you on. Of course, for that to work the URL has to point to PREPROD Shibboleth, either directly through the F5 or through an SSH tunnel from localhost.

Change the EntityID at the end of theĀ "Unsolicited/SSO" URL and you can verify that the right attributes are sent to any particular Service Provider.

SP Initiated

The IdP Initiated test was simplified because the code that handles the "Unsolicited/SSO" URL does not do any checks on the network address. Technically, the "Unsolicited/SSO" is a Shibboleth programming convention and not part of the SAML standard, so checks are not required.

However, if you go to the Service Provider and press a "Login from Yale" button or select Yale from a pulldown list of universities, then the SAML Request object generated by the Service Provider and the protocol by which it is sent to Shibboleth are part of the SAML standard, and that standard requires Shibboleth to do some extra checks that make the network configuration a bit more complicated.

Furthermore, while the network path from the Browser to the Service Provider (to send the Shibboleth Response) is just normal Yale networking and is not changed by the Shibboleth testing configuration, the SAML message that the SP sends to the Browser and then expects the Browser to deliver to Shib obviously is going to be affected by which Shib VM you want to use and how the Browser sends data to it.

Shibboleth processes the SAML Request first, before it even sends you to CAS in order to login. The Request has to go through a series of checks:

  • The EntityID to which the Request is addressed has to match the EntityID configured to this Shibboleth server through the "idp.entityid" property on the Jenkins Install. In the IdP Initiated testing you can use any Shibboleth (PROD, TEST, DEV, or Sandbox) and the Response will be generated and traced so you can look at its contents. It is only when the Response finally gets to the SP that it will be rejected if it comes from the wrong Shibboleth. But with an SP Initiated login you have to send the Request to the Shibboleth selected by the SP or you don't even start to do any processing. Because SPs are almost always configured to talk only to PROD, that means the Shibboleth you send the Request to has to think it has the production Shibboleth EntityID (that is, it must have been installed with the "idp.entityID= https://auth.yale.edu/idp/shibboleth" property).
  • The Service Provider will tell the Browser to send the Request (either by POSTing a form or by Redirect on a GET) to the SSO URL that the SP has in its copy of the Yale IdP Metadata. That will be a production URL, and so the Browser will be instructed to send the Request to "https://auth.yale.edu/idp/..." Since that will not be the actual URL of the test machine, you will have to use one of the tools described in the Client Configuration document to rewrite or reroute the request to the test VM.
  • Shibboleth will validate the digital signature on the Request, but that will always work because the SP is genuine and is not itself being tested.

Now we get to the last test, and that is the hardest and requires a lot more description than the previous simple tests. The SAML protocol requires a Request to have internal XML fields containing both the EntityID of the IdP to which the message is sent and also the Single Sign On URL to which it is being sent. Assuming the SP uses our production Metadata, it will include in the XML one of two URLs, "https://auth.yale.edu/idp/profile/SAML2/POST/SSO" or "https://auth.yale.edu/idp/profile/SAML2/Redirect/SSO", depending on which of two mechanisms it uses to send the Request.

Whatever mechanism you used in the Browser to rewrite or reroute this URL is not going to change the second copy of the same URL in the XML, and the problem is that SAML requires and Shibboleth implements a check that the URL in the XML is the same as the URL that Shibboleth believes was used to deliver the Request.

You can download the Shibboleth source and find the code that generates the URL and the other code that compares the two strings. Some of the data comes from the HTTP Host header sent to Shibboleth, and some comes from Tomcat. If the two strings don't match, Shibboleth writes an error message to the log containing the two strings it is comparing. You cannot change the string the SP sends in the XML, which will always be "https://auth.yale.edu/idp/profile/SAML2/POST/SSO", so you have to change the way the test service is configured and the network path between the browser and the test server to fix the problem if the non matching string in the log is:

  • "http://localhost:8080/" - The Host header contains the network address you are actually using instead of the fake network address you are trying to pretend to use. Change the hosts table or use Charles proxy to get a Host header with "auth.yale.edu".
  • "http://auth.yale.edu" - Better, but Tomcat has decided this is not https
  • "http://auth.yale.edu:8080" - Same thing, but now you have both the scheme (http) and the port (8080) screwed up.

You can spend many days trying to fix these problems, so the rest of this article is to explain how the problems arise and how networks are set up in general, and then the Client Setup article will explain the tools used to circumvent the problems.

Proxies and Tunnels

The first thing to say is that in almost no modern network is the hostname of the server that the Browser uses to get to Shibboleth ("auth.yale.edu") the actual name of the VM on which Shibboleth runs. In fact, it is almost never possible for the Browser to actually talk to Shibboleth directly. For security reasons, the network addresses and firewalls are set up to block outside access to server VMs, and a front end proxy machine provides the connection between the Browser and the Server. At Yale, that Proxy machine is called the F5.

Proxies have been part of HTTP since the early days of the World Wide Web. Originally they were used when the Internet was slow and it did not make sense for hundreds of computers at Yale to each independently download their own copies of widely used web pages. Today, you can put a proxy:

  • On the same computer as the Browser, but this is typically used only for testing.
  • Somewhere on campus to keep local copies of commonly used pages (the original use but the internet is faster today and this is not required any more)
  • Between the secure environment of the servers in the machine room and the outside world of untrusted requesters.
  • On the same machine as the server, because Tomcat runs as an ordinary user and you need the proxy to bind to ports 80 or 443, which require more privilege than Tomcat has.

As a developer testing code, you probably only have control over the first type of Proxy, and if you chose to use it then we recommend Charles Web Debugging Proxy as the simplest tool.

However, if you run a test and the SAML Request send by the SP is being rejected because the generated string does not match the expected URL, then something is going wrong and it could be with any of the other intermediate devices or it could be a Tomcat configuration problem. So you have to understand something about how this stuff works in order to debug it.

The good news is that Tomcat fully expects that one or more proxies will exist between the Browser and the server VM, so it is quite flexible in its configuration. Shibboleth is not as flexible, but the fact that it can work at all means that if you get the proxies configured right then everything will be OK.

When the Browser generates any HTTP request, it creates a Host header. This header contains the protocol, hostname, and port number from the URL that the Browser is using to get to the application. For a request that thinks it is going to production Shibboleth, this is

Host: https://auth.yale.edu

This header can go through the network and the F5 unmodified, or it can be changed and there are other network standards for other headers that might be generated by the F5 or any other device that receives, modifies, and forwards the request. The people who configure these network devices know all these conventions, and production Shibboleth receives data through a similar path with a similar set of header modifications.

So if you trap a Service Provider generated SAML Request and decide to forward it to a test Shibboleth server, things will work correctly provided that the Shibboleth server is configured with the same EntityID as production and that when the SAML Request arrives at the test server, passes through Tomcat, and is presented to Shibboleth that the Host header (and any other headers commonly generated by machines like the F5) convince Shibboleth that this request was originally addressed to "https://auth.yale.edu/idp".

Although there will be at any time one or more specific network configurations for accomplishing this result, there are lots of rules and tricks and software that can accomplish the same thing in various ways. The thing to remember is that if you try to login to a Service Provider with a test Shibboleth, and instead of getting a CAS login you get a message saying that the request did not meet security restrictions, and the Shibboleth log contains an error message saying that the message was addressed to "https://auth.yale.edu/idp" but Shibboleth has decided that its own network address is "http://auth.yale.edu/idp" (http not https), or "https://auth.yale.edu:8080/idp" (a port number got added), or "http://localhost:8080/idp" (you didn't fake anything out at all), then you have not set the HTTP headers and the network path right and you have to map out all the intermediate boxes and tunnels through which the request is passing to figure out what is wrong or missing.

The problem is that some of this path may not be under the control of the developer or tester, and if you try and create a path that is completely under your control you now have to learn more about the configuration of Tomcat and HTTP proxy tools, which are normally a problem for someone else.

Some successful recipes will be provided in the Testing Setup document, but if you decide to deviate from them you need to understand the problem described above and figure out new solutions.

  • No labels