This page is supplemental documentation of how redirects work in CAS 2.
CAS 2 behavior is governed by the specification.
CAS server may issue redirects in response to requests for its /login URL, which is mapped to the Login servlet.
<!-- Login --> <servlet> <servlet-name>Login</servlet-name> <servlet-class>edu.yale.its.tp.cas.servlet.Login</servlet-class> </servlet> <!-- ... ---> <servlet-mapping> <servlet-name>Login</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> |
The LoginServlet dispatches requests considering
The Login servlet will use a RequestDispatcher to forward to one of the relative URLs with which it was configured at servlet initialization.
For example:
app.getRequestDispatcher(serviceSuccess).forward(request, response); |
<!-- Login page URL --> <context-param> <param-name>edu.yale.its.tp.cas.loginForm</param-name> <param-value>/login.jsp</param-value> </context-param> <!-- Page URL for generic login success message --> <context-param> <param-name>edu.yale.its.tp.cas.genericSuccess</param-name> <param-value>/success.jsp</param-value> </context-param> <!-- Page URL for simple JavaScript-based redirection --> <context-param> <param-name>edu.yale.its.tp.cas.redirect</param-name> <param-value>/redirect.jsp</param-value> </context-param> <!-- Page URL for login success message when 'service' is specified --> <context-param> <param-name>edu.yale.its.tp.cas.serviceSuccess</param-name> <param-value>/goService.jsp</param-value> </context-param> <!-- Page URL for login success message + confirmation when 'service' is specified --> <context-param> <param-name>edu.yale.its.tp.cas.confirmService</param-name> <param-value>/warnService.jsp</param-value> </context-param> |
The two views that are interesting for purposes of this Wiki article about redirection in CAS 2 are edu.yale.its.tp.cas.redirect and edu.yale.its.tp.cas.serviceSuccess .
The edu.yale.its.tp.cas.redirect view is the way that the Login servlet accomplishes CAS Gateway. It's CAS server giving up on authenticating this user transparently and redirecting back to the service rather than forcing interactive authentication.
By default this is implemented in redirect.jsp:
<%@ page session="false" %> <% String serviceId = (String) request.getAttribute("serviceId"); %> <html> <head> <title>Yale Central Authentication Gateway</title> <script> window.location.href="<%= serviceId %>"; </script> </head> <body bgcolor="#0044AA"> <noscript> <p> Click <a href="<%= serviceId %>">here</a> to access the service you requested. </p> </noscript> </body> </html> |
This redirect is accomplished by means of a JavaScript script, with a fallback of simple HTML with a link the user can click if he has JavaScript turned off.
edu.yale.its.tp.cas.serviceSuccess is more interesting. It is CAS server attempting to redirect back to the service with a ticket.
<%@ page session="false" %> <% String serviceId = (String) request.getAttribute("serviceId"); String token = (String) request.getAttribute("token"); String service = null; boolean safari = true; // will set this below if (serviceId.indexOf('?') == -1) service = serviceId + "?ticket=" + token; else service = serviceId + "&ticket=" + token; service = edu.yale.its.tp.cas.util.StringUtil.substituteAll(service, "\n", ""); service = edu.yale.its.tp.cas.util.StringUtil.substituteAll(service, "\r", ""); service = edu.yale.its.tp.cas.util.StringUtil.substituteAll(service, "\"", ""); // Set Refresh header on initial login only if user isn't using Safari. // Fixes security bug where Safari would repost login credentials to the // web application rather than to CAS. if (((String)request.getAttribute("first")).equals("false") || request.getHeader("User-Agent") == null || request.getHeader("User-Agent").indexOf("Safari") == -1) { safari = false; } %> <html> <head> <title>Yale Central Authentication Service</title> <% if (!safari) { %> <script> window.location.href="<%= service %>"; </script> <% } %> </head> <body bgcolor="#0044AA" link="#ffffff" alink="#ffffff" vlink="#ffffff"> <% if (!safari) { %> <noscript> <% } %> <p>Login successful.</p> <p> Click <a href="<%= service %>">here</a> to access the service you requested. </p> <% if (!safari) { %> </noscript> <% } %> </body> </html> |
Provided the user isn't using Safari, this redirect is accomplished by means of a JavaScript script, with a fallback of simple HTML with a link the user can click if he has JavaScript turned off. If the user is using Safari, then it will always render the manual link.
(A potential improvement would be to only suppress the JavaScript redirect for Safari in the case where the password or other primary credential is present on the request.)