Spring Security and CAS Interaction Sequence
Spring Security and CAS Interaction Sequence
The basic interaction between a web browser, CAS server and a Spring Security-secured service is as follows:
-
The web user is browsing the service's public pages. CAS or Spring Security is not involved.
-
The user eventually requests a page that is either secure or one of the beans it uses is secure. Spring Security's
ExceptionTranslationFilter
will detect theAccessDeniedException
orAuthenticationException
. -
Because the user's
Authentication
object (or lack thereof) caused anAuthenticationException
, theExceptionTranslationFilter
will call the configuredAuthenticationEntryPoint
. If using CAS, this will be theCasAuthenticationEntryPoint
class. -
The
CasAuthenticationEntryPoint
will redirect the user's browser to the CAS server. It will also indicate aservice
parameter, which is the callback URL for the Spring Security service (your application). For example, the URL to which the browser is redirected might behttps://my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_spring_cas_security_check
. -
After the user's browser redirects to CAS, they will be prompted for their username and password. If the user presents a session cookie which indicates they've previously logged on, they will not be prompted to login again (there is an exception to this procedure, which we'll cover later). CAS will use the
PasswordHandler
(orAuthenticationHandler
if using CAS 3.0) discussed above to decide whether the username and password is valid. -
Upon successful login, CAS will redirect the user's browser back to the original service. It will also include a
ticket
parameter, which is an opaque string representing the "service ticket". Continuing our earlier example, the URL the browser is redirected to might behttps://server3.company.com/webapp/j_spring_cas_security_check?ticket=ST-0-ER94xMJmn6pha35CQRoZ
. -
Back in the service web application, the
CasAuthenticationFilter
is always listening for requests to/j_spring_cas_security_check
(this is configurable, but we'll use the defaults in this introduction). The processing filter will construct aUsernamePasswordAuthenticationToken
representing the service ticket. The principal will be equal toCasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER
, whilst the credentials will be the service ticket opaque value. This authentication request will then be handed to the configuredAuthenticationManager
. -
The
AuthenticationManager
implementation will be theProviderManager
, which is in turn configured with theCasAuthenticationProvider
. TheCasAuthenticationProvider
only responds toUsernamePasswordAuthenticationToken
s containing the CAS-specific principal (such asCasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER
) andCasAuthenticationToken
s (discussed later). -
CasAuthenticationProvider
will validate the service ticket using aTicketValidator
implementation. This will typically be aCas20ServiceTicketValidator
which is one of the classes included in the CAS client library. In the event the application needs to validate proxy tickets, theCas20ProxyTicketValidator
is used. TheTicketValidator
makes an HTTPS request to the CAS server in order to validate the service ticket. It may also include a proxy callback URL, which is included in this example:https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_spring_cas_security_check&ticket=ST-0-ER94xMJmn6pha35CQRoZ&pgtUrl=https://server3.company.com/webapp/j_spring_cas_security_proxyreceptor
. -
Back on the CAS server, the validation request will be received. If the presented service ticket matches the service URL the ticket was issued to, CAS will provide an affirmative response in XML indicating the username. If any proxy was involved in the authentication (discussed below), the list of proxies is also included in the XML response.
-
[OPTIONAL] If the request to the CAS validation service included the proxy callback URL (in the
pgtUrl
parameter), CAS will include apgtIou
string in the XML response. ThispgtIou
represents a proxy-granting ticket IOU. The CAS server will then create its own HTTPS connection back to thepgtUrl
. This is to mutually authenticate the CAS server and the claimed service URL. The HTTPS connection will be used to send a proxy granting ticket to the original web application. For example,https://server3.company.com/webapp/j_spring_cas_security_proxyreceptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH
. -
The
Cas20TicketValidator
will parse the XML received from the CAS server. It will return to theCasAuthenticationProvider
aTicketResponse
, which includes the username (mandatory), proxy list (if any were involved), and proxy-granting ticket IOU (if the proxy callback was requested). -
Next
CasAuthenticationProvider
will call a configuredCasProxyDecider
. TheCasProxyDecider
indicates whether the proxy list in theTicketResponse
is acceptable to the service. Several implementations are provided with Spring Security:RejectProxyTickets
,AcceptAnyCasProxy
andNamedCasProxyDecider
. These names are largely self-explanatory, exceptNamedCasProxyDecider
which allows aList
of trusted proxies to be provided. -
CasAuthenticationProvider
will next request aAuthenticationUserDetailsService
to load theGrantedAuthority
objects that apply to the user contained in theAssertion
. -
If there were no problems,
CasAuthenticationProvider
constructs aCasAuthenticationToken
including the details contained in theTicketResponse
and theGrantedAuthority
s. -
Control then returns to
CasAuthenticationFilter
, which places the createdCasAuthenticationToken
in the security context. -
The user's browser is redirected to the original page that caused the
AuthenticationException
(or a custom destination depending on the configuration).
It's good that you're still here! Let's now look at how this is configured