SSO используя Jasig CAS Server 4.0.0. Часть 2

Мы уже подняли сервер Jasig CAS теперь пора немного его кастомизировать. Зачем это нужно? Сейчас ми авторизируемся используя статического пользователя, но мы это исправим и сделаем возможность получать пользователя из внешних систем или БД.Хочу напомнить что ранее уже мы расматривали как сконфигурировать и поднять Jasig CAS Server 4.0.0 в посте SSO используя Jasig CAS Server 4.0.0. Часть 1Теперь мы немного кастомизируем систему входа, для для того чтобы мы могли получать нашего User с внешних систем либо БД.Создание структуры и DTOДавайте теперь создадим в своем проекте в папке src/ следующую структуру проекта: 624535b6eadefdb8d2ae8c0484220663.png

теперь в пакете dto создадим CASUser он нужен для удобства управления нашим пользователем.Вот содержимое 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; } } Тепрь мы пожем использовать этот объект для манипуляции пользователем в системе.Создание сервиса Теперь в пакете service нам нужно создать интерфейс CASUserService со следующим содержимым: package com.devcolibri.sso.service;

import com.devcolibri.sso.dto.CASUser; import org.jasig.cas.authentication.UsernamePasswordCredential;

public interface CASUserService {

CASUser getByCredential (UsernamePasswordCredential credential);

} Как видите в этом интерфейсе есть всего один метод, который мы должны реализовать, этот метод необходим для получения пользователя с внешней системы либо БД.Теперь создаем в том же пакете класс который реализует этот интерфейс, я назвал его CASUserServiceImpl так как мы используем Spring Framework нам нужен интерфейс для DI.Вот реализация нашего интерфейса, а именно класс CASUserServiceImpl: 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; }

} Я сделал получение пользователя в виде mock данных, но в следующих частях мы поменяем эту реализацию.Пока можно представить что эти данyые получаются например с БД и они валидные, но в будущем мы это поменяем.Теперь для логина мы будем использовать логин: test и пароль: test.Создание кастомного Hendler Пришло время кастомизации CAS 4. Кастомизировать мы будем стандартный способ аунтентификации на свой.Для этого в пакете handler создаем класс ServerUsernamePasswordAuthenticationHandler наследуемся от AbstractUsernamePasswordAuthenticationHandler и реализуем метод authenticateUsernamePasswordInternal (): 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 {

@Autowired private CASUserService casUserService;

@Override protected HandlerResult authenticateUsernamePasswordInternal (UsernamePasswordCredential credential) throws GeneralSecurityException, PreventedException {

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); } } Таким образом, мы проверяем на валидность полученные данные от пользователя с формы и данные, полученные с сервиса, в случае если логин и пароль совпадает с теми, что вернул сервис, пользователь будет аутентифицирован.Финальное конфигурирование Теперь осталось скопировать с overlays/org.jasig.cas.cas-server-webapp-4.0.0/WEB-INF/deployerConfigContext.xml файл и положить его себе в проект как показанно на скрине ниже: c2c613472c73d76536104d791e71d814.pngТеперь заходи в этот файл и ищем 96 строку или TODO: TODO: Replace this component with one suitable for your enviroment.Это стандартный handler со статическим логином и паролем.Теперь удаляем bean c id=«primaryAuthenticationHandler»:

И на его место описываем наш bean handler: Также надо указать наш сервис: Полная структура проекта: eec10e8f395e092ec4e4f366c1670cbe.pngПосле этого пересобираем проект, деплоим и логинимся под пользователем test.Вы должны, залогинится. В следующей части мы напишем клиент для нашего сервера.

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

© Habrahabr.ru