SSO using Jasig CAS Server 4.0.0. Part 2

  • Tutorial
We already raised the Jasig CAS server, now it's time to customize it a bit. Why is this needed? Now we log in using a static user, but we will fix this and make it possible to get the user from external systems or the database.

I want to remind you that earlier we looked at how to configure and upgrade Jasig CAS Server 4.0.0 in the SSO post using Jasig CAS Server 4.0.0. Part 1
Now we customize the login system a bit so that we can receive our User from external systems or the database.

Structure Creation and DTO


Let's now create the following project structure in our src / folder in our project :



now in the dto package we will create CASUser for the convenience of managing our user.
Here are the contents of CASUser:

package com.devcolibri.sso.dto;
import java.io.Serializable;
public class CASUser implements Serializable {
    private String username;
    private String password;
    public CASUser(String username, String password) {
        this.username = username;
        this.password = password;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

Now we can use this object to manipulate the user in the system.

Service Creation


Now in the service package we need to create a CASUserService interface with the following contents:
package com.devcolibri.sso.service;
import com.devcolibri.sso.dto.CASUser;
import org.jasig.cas.authentication.UsernamePasswordCredential;
public interface CASUserService {
    CASUser getByCredential(UsernamePasswordCredential credential);
}

As you can see, there is only one method in this interface that we must implement, this method is necessary to get the user from an external system or database.
Now we create a class in the same package that implements this interface, I named it CASUserServiceImpl since we use the Spring Framework we need an interface for DI .
Here is the implementation of our interface, namely the CASUserServiceImpl class:
package com.devcolibri.sso.service;
import com.devcolibri.sso.dto.CASUser;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.springframework.stereotype.Service;
@Service
public class CASUserServiceImpl implements CASUserService {
    @Override
    public CASUser getByCredential(UsernamePasswordCredential credential) {
        String usernameMock = "test";
        String passwordMock = "test";
        CASUser user = null;
        if(credential.getUsername().equals(usernameMock) && credential.getPassword().equals(passwordMock)) {
            user = new CASUser(usernameMock, passwordMock);
        }
        return user;
    }
}

I did get the user as mock data, but in the next parts we will change this implementation.
For now, one can imagine that these data are obtained, for example, from the database and they are valid, but in the future we will change this.
Now for the login we will use the login: test and password: test .

Creating Custom Handler


It's time to customize CAS 4. We will customize the standard authentication method to your own.
To do this, in the handler package, create the ServerUsernamePasswordAuthenticationHandler class , inherit from AbstractUsernamePasswordAuthenticationHandler and implement the authenticateUsernamePasswordInternal () method :

package com.devcolibri.sso.handler;
import com.devcolibri.sso.dto.CASUser;
import com.devcolibri.sso.service.CASUserService;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.principal.SimplePrincipal;
import org.springframework.beans.factory.annotation.Autowired;
import javax.security.auth.login.AccountNotFoundException;
import java.security.GeneralSecurityException;
public class ServerUsernamePasswordAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {
    private CASUserService casUserService;
    @Override
    protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential)
            throws GeneralSecurityException, PreventedException {
        casUserService = new CASUserServiceImpl();
        CASUser user = casUserService.getByCredential(credential);
        if(credential.getUsername().equals(user.getUsername()) && credential.getPassword().equals(user.getPassword())) {
            user = new CASUser(user.getUsername(), user.getPassword());
        }
        if (user == null) {
            throw new AccountNotFoundException(user.getUsername() + " not found.");
        }
        return createHandlerResult(credential, new SimplePrincipal(user.getUsername()), null);
    }
}

Thus, we check the validity of the data received from the user from the form and the data received from the service, if the username and password match those returned by the service, the user will be authenticated.

Final configuration


Now it remains to copy the file from overlays / org.jasig.cas.cas-server-webapp-4.0.0 / WEB-INF / deployerConfigContext.xml and put it into your project as shown in the screenshot below:

Now go to this file and look for 96 string or TODO: TODO: Replace this component with one suitable for your enviroment.
This is a standard handler with a static username and password.

Now remove the bean c id = "primaryAuthenticationHandler":

And in its place we describe our bean handler:

The full structure of the project:


After that we rebuild the project, deploy and log in as the user test .
You must log in. In the next part, we will write a client for our server.

Github : https://github.com/alexbarchuk/local-cas

Also popular now: