...

четверг, 17 июля 2014 г.

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/ следующую структуру проекта:


теперь в пакете 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 файл и положить его себе в проект как показанно на скрине ниже:



Теперь заходи в этот файл и ищем 96 строку или TODO: TODO: Replace this component with one suitable for your enviroment.

Это стандартный handler со статическим логином и паролем.

Теперь удаляем bean c id=«primaryAuthenticationHandler»:



<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
<property name="users">
<map>
<entry key="casuser" value="Mellon"/>
</map>
</property>
</bean>




И на его место описываем наш bean handler:

<bean id="primaryAuthenticationHandler"
class="com.devcolibri.sso.handler.ServerUsernamePasswordAuthenticationHandler" />




Также надо указать наш сервис:

<bean id="CASUserService"
class="com.devcolibri.sso.service.CASUserServiceImpl" />




Полная структура проекта:


После этого пересобираем проект, деплоим и логинимся под пользователем test.

Вы должны, залогинится. В следующей части мы напишем клиент для нашего сервера.


Github: http://ift.tt/1kaOKIQ


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий