...
Code Block | ||
---|---|---|
| ||
public Interface Ticket {
/**
* Get a String uniquely identifying this Ticket within this instance of CAS Server.
* The id must contain a substring that is drawn uniformly at random from a large space --
* this is vital to the security of a CAS implementation.
*/
public String getId();
/**
* Get the GrantingTicket from which this Ticket was generated.
* Returns null in the case where this Ticket was not created from a GrantingTicket.
*/
public GrantingTicket getGrantor();
/**
* Get the Date at which this Ticket was created.
* It is not expected that ticket consumers will use this method to themselves calculate
* expiry. Rather, timestamp of creation is an attribute of tickets, made available for such purposes
* as logging, verification that expiry is behaving properly, etc.
*/
public Date getTimestamp();
/**
* Is this ticket expired?
*/
public boolean isExpired();
}
|
GrantingTickets add to Ticket an additional property: the immediate authenticated Principal to which the GrantingTicket was issued. This might be a user Principal, in the case of the GrantingTicket that is stored into a secure cookie in a user's web browser, or this might be a service Principal, in the case of a GrantingTicket that was issued by secure callback to an application or to an otherwise authenticated application out there on the Internet.
...
Code Block | ||
---|---|---|
| ||
public interface ServiceTicket extends Ticket { /** * Get the Target to which this ServiceTicket is intended to authenticate the * chain of Principals represented by the grantor of this ticket. */ String getTarget(); /** * True if this ServiceTicket was created in the same transaction that created the granting ticket. * False otherwise. * This is how we implement the CAS 'renew' behavior -- ServiceTickets created simultaneous with * their GrantingTicket may succeed on validation with renew=true, but if this value is false * then validation with renew=true must fail. */ boolean createdInTxnThatCreatedGrantor(); } |
Why is the return value for getTarget() a String? Because it is an arbitrary identifer. By convention it is a URL – and its being a URL has special meaning in the case of applications redirecting to CAS to obtain a ServiceTicket – but there is no requirement that the target be a URL. The Target represents an opportunity for the Principal owning the GrantingTicket requesting this ServiceTicket to ensure that communicate with the ServiceTicket that it obtains can only be used to authenticate to the Target it intendsTarget that validates the ticket exactly what request is being authenticated.
What is authenticated by a ServiceTicket? When a ServiceTicket is validated, the validation response is a representation of the chain of Principals from associated with the GrantingTicket that granted the ServiceTicket, and the GrantingTicket (if any) that granted that GrantingTicket, and the GrantingTicket (if any) that granted that GrantingTicket, and so forth up the chain until we reach a GrantingTicket that was the first in the chain.
...
CAS 2.0 ServiceTickets are ServiceTickets the GrantingTicket of which has a Principal that is a user – an authenticated netid – and which itself has a grantor of null. Implementations of the CAS 2.0 "serviceValidate" and "validate" web targets will need to verify that the CAS 3.0 ServiceTicket they are validating in fact has a single GrantingTicket in the chain of grantors and that the Principal of that single grantor represents an authenticated netid.
The XML response associated with ServiceTickets in CAS 2.0 represents this special case where the chain of authenticated principals contained only a single Principal that represents an authenticated user.
Code Block | ||||
---|---|---|---|---|
| ||||
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'> <cas:authenticationSuccess> <cas:user>NetID</cas:user> </cas:authenticationSuccess> </cas:serviceResponse> |
Understanding traditional ProxyTickets in this new scheme
CAS 2.0 ProxyTickets are ServiceTickets the GrantingTicket of which has a Principal that is a service – an authetnicated proxy ticket receptor which received the PGT – and which itself has a grantor that is not null – that is the GrantingTicket issued to a previous authenticated service in the chain or to the end user's web browser.
Chains of authenticated principals
But all we have ever had is chains of authenticated principals. What we've been calling the "user" is merely the user at the top of the chain. What we've been calling ServiceTickets are merely the special case where the chain was of size one.
Perhaps an appropriate new representation for a validation response in CAS 3.0 would be something like:
Code Block | ||||
---|---|---|---|---|
| ||||
<cas:validationResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:principalChain>
<cas:principal>awp9</cas:principal>
<cas:principal>https://portal.yale.edu/CasProxyServlet</principal>
<cas:principal>https://mail.yale.edu/imap2XmlGateway</principal>
</cas:principalChain>
</cas:authenticationSuccess>
</cas:serviceResponse>
|
This representation can be used equally well for the case where the top Principal in the chain is a service, rather than a user in a web browser, to which the original GrantingTicket was issued:
Code Block | ||||
---|---|---|---|---|
| ||||
<cas:validationResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:principalChain>
<cas:principal>https://portal.yale.edu/CasTicketReceptorServlet</principal>
<cas:principal>https://portal.yale.edu/tshirtSalesPortlet/CasTicketReceptorServlet</principal>
</cas:principalChain>
</cas:authenticationSuccess>
</cas:serviceResponse>
|
It's turtles all the way down.