16 Feb 2017

Apereo CAS REST Authentication

Written by fabio

Within this short post I will provide several details to configure Apereo CAS to submit authentication requests to a remote REST endpoint. It has nothing to do with the native CAS REST API.
More highlights will be given about the response that has to be returned by the REST endpoint. For this purpose the open source identity manager Apache Syncope will be used to provide a sample endpoint returning verification results including principal id and principal attributes.


As reported into the relative section of the Apereo CAS guide, REST authentication is enabled by including the following dependencies in the WAR overlay:


This allows the CAS server to reach to a remote REST endpoint via a POST for verification of credentials. Credentials are passed via an Authorization header whose value is Basic XYZ where XYZ is a Base64 encoded version of the credentials. The response that is returned must be accompanied by a 200 status code where the JSON body should contain id and attributes fields, the latter being optional, which represent the authenticated principal for CAS. Attributes have to be returned as a JSON representation of a Map<String, Object>.

Now Apache Syncope has to be extended in order to provide a specific REST endpoint for our aims.

First of all we can implement the the transfer object to be used to return the principal.
See below an example.

package net.tirasa.samples;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LoginResponseTO {
  private String id;
  private final Map<String, Object> attributes;

  public LoginResponseTO() {
    attributes = new HashMap<String, Object>();

  public String getId() {
    return id;

  public void setId(String id) {
    this.id = id;

  public Map<String, Object> getAttributes() {
    return attributes;

This class can be added into the Syncope overlay project, under the following path

The next one is about the creation of the real REST endpoint.
First of all let’s define the REST service by providing the following class under the path

package org.apache.syncope.core.services;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.services.JAXRSService;

  public interface TirasaUserService extends JAXRSService {
    Response login();

An then, maybe in the same path, the following implementation

package org.apache.syncope.core.services;

import java.util.List;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.to.UserTO;
import org.apache.syncope.core.rest.controller.UserController;
import org.springframework.beans.factory.annotation.Autowired;
import net.tirasa.samples.LoginResponseTO;

@Service public class TirasaUserServiceImpl extends AbstractServiceImpl implements TirasaUserService {
  private UserController userController;

  public Response login() {
    UserTO userTO = userController.readSelf();
    return Response.status(200).entity(createLoginResponseTO(userTO)).build();

  private LoginResponseTO createLoginResponseTO(UserTO userTO) {
    LoginResponseTO loginResponseTO = new LoginResponseTO();

    // add further custom attributes
    loginResponseTO.getAttributes().put("attr1", "XXX");
    loginResponseTO.getAttributes().put("attr2", "YYY");

    // return the authenticated principal
    return loginResponseTO;

Compile and deploy (or start it in embedded mode) your Syncope overlay and create your sample user.

Let’s come back to the CAS …

The following settings have to be added into "cas.properties" file in order to enable REST authentication against Apache Syncope specific endpoint:

cas.authn.rest.uri=http://<syncope host>.<domain>:<port>/syncope/rest/tirasa/self

The configuration is almost completed here. By the way, in order to be able to retrieve returning principal attributes a further step is required: configure attributeReleasePolicy for your protected service. See the example below and pay attention to allowedAttributes parameter into attributeReleasePolicy section.

  "@class": "org.apereo.cas.services.RegexRegisteredService",
  "serviceId": "^http://saples.tirasa.net:808./.*",
  "name": "tirasa",
  "id": 3,
  "description": "Allows tirasa services",
  "evaluationOrder": 1,
  "usernameAttributeProvider": {
    "@class": "org.apereo.cas.services.PrincipalAttributeRegisteredServiceUsernameProvider",
    "usernameAttribute": "id"
  "logoutType": "BACK_CHANNEL",
  "attributeReleasePolicy": {
    "@class": "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy",
    "authorizedToReleaseCredentialPassword": false,
    "authorizedToReleaseProxyGrantingTicket": false,
    "allowedAttributes": ["java.util.ArrayList", ["id", "attr1", "attr2"]]
  "accessStrategy": {
    "@class": "org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy",
    "enabled": true,
    "ssoEnabled": true,
    "caseInsensitive": true

Redeploy your CAS instance and enjoy your solution.


« Return