The primary mechanism by which the SP makes attribute and other session information available to applications is by "exporting" the data to a set of environment variables or HTTP request headers that are generally exposed to web applications using the CGI (Common Gateway Interface) defined in the early days of the web.
Originally, web applications ran as scripts or executable programs invoked by web servers as a separate process. The CGI was a specification for a set of environment variables passed to the new process by the web server. In addition to a set of relatively fixed elements, every request header attached to the request was translated into a variable by normalizing it and prefixing it with "HTTP_".
While most applications today are not written as actual "CGI applications" and tend to be executed by interpreted scripting plugins deployed with the web server, the CGI and its conventions are supported in some form by all development tools.
Within each CGI variable or header (see below), multiple attribute values are separated by a semicolon, and semicolons in values are escaped with a backslash. The data should be interpreted as UTF-8, which is a superset of ASCII.
Currently, the SP supports the use of environment variables on all versions of Apache. You should always use this mechanism with web servers that support it.
The safest mechanism, and the default for servers that allow for it, is the use of environment variables. The term is somewhat generic because environment variables don't necessarily always imply the actual process environment in the traditional sense, since there's often no separate process. It really refers to a set of controlled data elements that the web server supplies to applications and that cannot be manipulated in any way from outside the web server. Specifically, the client has no say in them.
In many cases, access to environment variables is even case sensitive; a mapped attribute with an
id of "My-Attribute" might only be accessible as a variable with that exact name. Accessing "MY-Attribute" or "My_Attribute" often won't work. This is a good thing, since it's unambiguous.
Note however that Perl applications using the CGI library will have environment variable names altered: hyphens ('-') are turned into underscore ('_'). The above example will be accessed as "My_Attribute".
On IIS and Sun/iPlanet, the request header mechanism is the only one supported. It is optional, and off by default, on all versions of Apache.
Unfortunately, not all web servers currently expose a mechanism to create custom variables from within server extensions. This is a bug; all web servers should support this in some way, but IIS and Sun/iPlanet do not.
On these platforms, the SP is forced to substitute the use of custom HTTP request headers. This is convenient, in that the CGI requires custom headers to be passed along to applications, but is also dangerous and difficult to secure. The SP has had at least two separate major security patches resulting from this mechanism. This is because the header mechanism is really about passing information from the client to the application; any browser can be manipulated to supply arbitrary headers quite easily with little skill.
To defend against this, the SP has a number of protections designed to clear out any data supplied by the client that might overlap with the headers it creates. But this is very difficult to get right in practice, and recent versions include a much-enhanced NativeSPSpoofChecking mechanism for actually detecting and blocking requests that carry such headers.
When using headers, the main difference is that instead of using the names defined via the mapping process, the application must prefix them with "HTTP_", and in most tools upcase the rest of the name as well. The specifics vary by tool, and in the case of IIS and ASP.NET are even more bizarre because of serious flaws in IIS' CGI implementation.
A fair amount of detail on this can be found in the secadv_20090615 topic. The most particular point about ASP.NET is that it provides access to both the transformed headers (all caps, with the HTTP_ prefix) via the
ServerVariables collection, and the untransformed input headers via the
Headers collection. The latter is much safer to use.
The SP cannot populate "REMOTE_USER" on the IIS platform. It is supported on all others.
"REMOTE_USER" is a special environment variable established by the CGI for use in passing the "authenticated username" to applications. It is NOT a header, and is designed to be set only when the web server is informed by a module that the user accessing the application is known. It is empty or unset otherwise. In many tools, it may be accessed outside of the usual APIs and may have a dedicated function for obtaining it (e.g., Java servlets have a getRemoteUser method).
Shibboleth is somewhat unique among SSO tools in that it does not necessarily allow for "REMOTE_USER" to be set, even if a user has logged in. This is for two reasons: privacy and extensibility.
In some cases, the user's IdP may not provide enough information to uniquely identify the user, but instead supply only an attribute intended to grant the user access to something. Or it's possible that the user's own privacy requirements preclude supplying identifying information. In either case, the application might still have to run but will not have a username to key off of. This can certainly be treated as an error by the application. What it can't do is crash the application (unless you're fine with people thinking your site is designed by incompetents).
The other reason why "REMOTE_USER" is handled differently by the SP is the generic notion of identity that underlies federation. There is no single way of identifying users once you're working on a global scale. Different technologies all have their own approaches, and no single attribute or syntax can be assumed. SAML itself leaves this issue completely open. As a result, the SP handles "REMOTE_USER" by leaving it up to the configuration as to which of several attributes can be used to populate it.
As noted above, for technical reasons, IIS does not allow the "REMOTE_USER" variable to be set with the constraints imposed by the use of Shibboleth. For reasons of compatibility with some application tools, specifically Cold Fusion, the SP has an unfortunate feature on IIS. It tries to circumvent the problem by creating a header variable (internally named "remote-user") that maps to a request header variable named "HTTP_REMOTE_USER".
This was a mistake, and has already led to (now patched) security problems. While not formally deprecated, you should consider use of this feature highly discouraged, and should not develop new applications based on this header name. There is no reason to do so, because it will not allow compatibility with applications expecting "REMOTE_USER". Instead, you should use the specific header name corresponding to the underlying attribute mapping you want to use, or multiple such mappings if necessary. This is much less confusing and less likely to cause problems in the future.
Custom SP Variables
Most of the variables created by the SP are controlled by you, and correspond to mapped attributes. A few are built into the SP and can't be renamed. Currently these are hardwired but in a future version most of them will be produced through the use of the recently introduced attribute extractor of type "Assertion". The built-in variables can be disabled (to avoid duplication with the extractor) with the content setting of
applicationId property derived for the request.
The internal session key assigned to the session associated with the request.
The entityID of the IdP that authenticated the user associated with the request.
The ISO timestamp provided by the IdP indicating the time of authentication.
<AuthnContextClassRef> value supplied by the IdP, if any.
<AuthnContextClassRef> value supplied by the IdP, if any.
<AuthnContextDeclRef> value supplied by the IdP, if any.
|Shib-Handler2.6||The self-referential base location of the SP's "handlers" for use by applications in requesting login, logout, etc.|
Struts 2 Issue
An issue has been identified using environment variable access using Struts 2. When accessing a request attribute whose name contains a hyphen, and the attribute does not exist in the session, rather than returning a null value the Struts environment returns an instance of java.math.BigDecimal with the value '0'. This is related to Struts use of a wrapped servlet request and evaluation of the attribute name as an OGNL expression. Applications retrieving attribute data within this framework should take care to check the return value of request.getAttribute(name) for attribute names containing a hyphen. This affects all the custom SP variables noted above as well as certain default attribute names such as 'persistent-id'.
Shibboleth attributes are by default UTF-8 encoded. However, depending on the servlet contaner configuration they are interpreted as ISO-8859-1 values. This causes problems with non-ASCII characters. The solution is to re-encode attributes, e.g. with:
String value= request.getHeader("givenName");
value= new String( value.getBytes("ISO-8859-1"), "UTF-8");
Shibboleth attributes are by default UTF-8 encoded. However, in Coldfusion they are interpreted as ISO-8859-1 values. This causes problems with non-ASCII characters. The solution is to re-encode attributes, e.g. with:
<cfset surname = charsetEncode(toBinary(toBase64(CGI.givenName,"iso-8859-1")),"utf-8")>
Ruby on Rails