11

at our company we have multiple web applications deployed that are secured through SSO using CAS server. A user requests an url of an application, and if not already authenticated, gets redirected to the CAS server login page. In case of successful authentication the user will be redirected back to the originally requested url. common workflow and works perfectly.

but, we also want to protect our REST Apis using CAS Server. Our prefered flow would be as follows:

  • a user creates a token for an application REST Api
  • using this token the user can request a temporary access token (like the CAS token)
  • in each request to the REST Api, the user includes the temporary access token either as a HTTP Header or a request parameter
  • the REST Api application checks the provided temporary token against the CAS server for validity

sounds like OAuth, which CAS server does support, except that the user is not asked for a credentials at any time, but we'd also like to provide authentication for services i.e., other applications calling our APIs:

  • developer asks for a REST Api token (which is associated with a CAS user)
  • application requests a temporary access token using the Api token
  • further requests to the Api include the temporary access token either as a HTTP header or a request parameter
  • REST Api application checks temporary access token against CAS server for validity

We want our REST Api applications to know nothing about user credentials, they don't even have access to the user database, which works just fine for humans using the application (redirect to CAS login page).

I don't know how we can implement this flow without having to heavily customize CAS server and implement this behavior by ourselves.

Google uses JWT for OAuth 2.0 for Server to Server Applications, which seems like the way to go.

I'd appreciate it if anyone can provide some hints or alternatives (to CAS server). Maybe someone has already implemented this pattern using CAS server and can provide some information on this issue.

Best Regards, Marco

marco.eig
  • 4,209
  • 2
  • 18
  • 26

2 Answers2

11

finally we got it working in an easy way:

at CAS server:

  • implemented a REST endpoint that allows clients to obtain a CAS service ticket ST by providing a clientId and a clientSecret for a specific service-url. clientId and clientSecret are considered to be username and password respectively.
    • the REST endpoint creates a new custom TokenBasedAuthenticationCredentials object and passes it to the CentralAuthenticationService to grant a TGT and a ST (the service-url for which the ST is granted is associated with the clientId and clientSecret pair and can be obtained from e.g., user-database clientId|clientSecret|serviceUrl).
  • implemented a new AuthenticationHandler and CredentialsToPrcincipalResolver which support TokenBasedAuthenticationCredentials only.

the REST endpoint /cas/../token returns a JSON object:

{ serviceTicket: 'ST-ALKSJDFLSJDFLKJ-Ljksdf-sdflkjsf' }

at (Spring-based) CAS client (protected resource):

  • enabled authenticateAllArtifacts
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
    <property name="service" value="${cas.service.url}" />
    <property name="sendRenew" value="false" />
    <property name="authenticateAllArtifacts" value="true"/>
</bean>
  • extend CasAuthenticationFilter and override obtainArtifact(request) to obtain the ST from the HTTP Authorization-Header

now, the client, which wants to access your protected resources, can

  • obtain a ST from the CAS server,
  • provide the ST in each request to the protected resource as Authorization-Header
GET /rest/foo/bar HTTP/1.1
Host: www.example.com
Authorization: CUSTOM_SCHEME ST-ALKSJDFLSJDFLKJ-Ljksdf-sdflkjsf

since CAS client CasAuthenticationFilter obtains artifacts (i.e., ST) on each request, the client gets authenticated in just a single request.

Additionally on CAS server, you can configure the ST to be valid for only n requests (the number of times the CAS client requests the serviceValidate url at CAS server).

I think this is a pretty good way without having to customize CAS server and client massively, and subsequently, creating critical security flaws.

marco.eig
  • 4,209
  • 2
  • 18
  • 26
0

Aren't service tickets designed to be one time use?

epdittmer
  • 488
  • 2
  • 4
  • 15
  • you can configure it to be valid only once. could you give me more information on why you think they are designed for one time use? – marco.eig Nov 21 '14 at 14:45
  • 1
    @reagten From my understanding exposing the service ticket in this way (basically using it as a token) introduces some security concerns (like no being able to control the usage of the service ticket). Wouldn't it be better to do the following. Retrieve TGT from CAS, authentication with user/password/TGT to CAS. Exchange the Service Ticket from the CAS REST API into an application specific token? This way the REST API only knows about the Token and not about the data associated with the user, nor can the client use the ST to call the CAS /validate endpoint directly (also ST can be IP locked) – epdittmer Nov 21 '14 at 19:56