Using CAS from external link or custom external form

Motivation

We wanted to be more flexible in the use of the login UI, so e.g. wanted to embed it in several places as a small panel. Moreover, we wanted to understand CAS as a pure service, not having to maintain layout information twice. Also, we wanted to support both, login postings from another site and direct login at the CAS server as a fallback.

Other proposed solutions

The Solution

The solution is to bypass the login form in case we post a "auto" HTTP parameter with value "true".

In that case, an auto-posting form will be rendered and posted to CAS as if a user had been authenticating himself.

As even without that modification, anybody can create a site whit a login / password form which would then post it from that server to the CAS server with 2 request (first one to retrieve the values of lt & execution, second one to post it & redirect the final user to the CAS server with the session retrieved from that second request), there is no security regression here.

Modification to CAS war

You just have to edit the casLoginView.jsp file and add those modification at the head and the tail of the file :

casLoginView.jsp
...
<%@ page contentType="text/html; charset=UTF-8" %>
<%
String auto = request.getParameter("auto");
if (auto != null && auto.equals("true")) {
%>
<html>
	<head>
		<script language="javascript">
			function doAutoLogin() {
				document.forms[0].submit();
			}
		</script>
	</head>
	<body onload="doAutoLogin();">
		<form id="credentials" method="POST" action="<%= request.getContextPath() %>/login?service=<%= request.getParameter("service") %>"> 
			<input type="hidden" name="lt" value="${loginTicket}" />
			<input type="hidden" name="execution" value="${flowExecutionKey}" />
			<input type="hidden" name="_eventId" value="submit" />
			<input type="hidden" name="username" value="<%= request.getParameter("username") %>" />
			<input type="hidden" name="password" value="<%= request.getParameter("password") %>" />
			<% if ("true".equals(request.getParameter("rememberMe"))) {%>
				<input type="hidden" name="rememberMe" value="true" />
			<% } %>
			
			<input type="submit" value="Submit" style="visibility: hidden;" />
		</form>
	</body>
</html>
<%
} else {
%>
<jsp:directive.include file="includes/top.jsp" />
...
<jsp:directive.include file="includes/bottom.jsp" />
<%
}
%>

Usages

With that modification done, you can create external links such as this one : 

You can also create some custom external form such as this one :

<html>
<head />
<body>
	<form method="GET" action="https://cas.example.com/cas/">
		<p>Username : <input type="text" name="username" /></p>
		<p>Password : <input type="password" name="password" /></p>
		<p>Remember me : <input type="checkbox" name="rememberMe" value="true" /></p>
		<p><input type="submit" value="Login !" /></p>
		<input type="hidden" name="auto" value="true" />
		<input type="hidden" name="service" value="http://app.example.com/myapp/" />
	</form>
</body>
</html>