Ответ 1
Я считаю, что OP не имеет никакого смысла отвечать. Тем не менее, это заслуживает всеобъемлющего ответа. На самом деле, я удивлен, что у него его еще нет.
Прежде всего, это плохая идея: такая договоренность, как предлагаемая OP, действительно слишком неуверенная. Тем не менее, решение описанной проблемы может быть хорошим прототипом для кого-то, создающего автолог для Liferay.
Теперь, скажем, вы хотите автоматически регистрировать любого пользователя, чье имя экрана отправляется в параметре строки запроса. Например, если один доступ http://localhost:8080/web/guest/home?insecurely_login_user=juju
, то Liferay в juju
пользователь должен войти в систему. Как это сделать? Выполните следующие шаги:
Создайте класс autologin
Во-первых, создайте плагин hook. В своем каталоге docroot/WEB-INF/src
создается класс, реализующий интерфейс com.liferay.portal.security.auth.AutoLogin
. В моем примере я назову его br.brandizzi.adam.liferay.insecure.InsecureAutoLogin
.
Интерфейс AutoLogin
имеет только один метод, называемый login()
, который ожидает два параметра (an HttpServletRequest
и HttpServletResponse
) и возвращает массив строк. Итак, мой класс будет выглядеть следующим образом:
public class InsecureAutoLogin implements AutoLogin {
@Override
public String[] login(HttpServletRequest request,
HttpServletResponse response) throws AutoLoginException {
// TODO Auto-generated method stub
return null;
}
}
Метод AutoLogin.login()
попытается получить информацию, необходимую для аутентификации из многих источников, главным образом объекта запроса. Если он решает, что пользователь должен войти в систему, он возвращает массив с соответствующими данными для аутентификации; если он решает не регистрировать пользователя, он может просто вернуть null
.
В нашем случае мы пытаемся получить имя пользователя из параметра insecurely_login_user
из запроса. Если есть такой параметр, мы продолжим логин; если такого параметра нет, он просто возвращает null
:
String screenName = request.getParameter("insecurely_login_user");
if (screenName == null || screenName.isEmpty()) {
return null;
}
Итак, у нас есть имя экрана. Что делать сейчас? Позвольте нам получить пользователя из базы данных с тем же именем экрана.
long companyId = PortalUtil.getCompanyId(request);
User user = UserLocalServiceUtil.getUserByScreenName(companyId,
screenName);
Если пользователь, имеющий такое имя экрана, существует, он будет извлечен и отнесен к переменной user
. В этом случае аутентификация должна быть успешной, и класс autologin должен вернуть массив из трех строк - учетных данных. Таковы значения, которые должны быть возвращены в качестве учетных данных в порядке их появления в массиве:
- идентификатор пользователя как строка
- пароль пользователя, который может быть зашифрован или нет;
- логическое значение, отличное от строки, указывающее, зашифрован ли пароль.
Итак, вот строка:
return new String[] {
String.valueOf(user.getUserId()),
user.getPassword(),
String.valueOf(user.isPasswordEncrypted())
};
Если пользователь не найден, исключение будет выбрано. Итак, мы должны окружить код выше конструкцией try
/catch
. Если выбрано исключение, просто верните null
:
try {
long companyId = PortalUtil.getCompanyId(request);
User user = UserLocalServiceUtil.getUserByScreenName(companyId,
screenName);
return new String[] { String.valueOf(user.getUserId()),
user.getPassword(),
String.valueOf(user.isPasswordEncrypted()) };
} catch (Exception e) {
return null;
}
В конце концов, это мой класс InsecureAutoLogin
:
public class InsecureAutoLogin implements AutoLogin {
public String[] login(HttpServletRequest request,
HttpServletResponse response) throws AutoLoginException {
String screenName = request.getParameter("insecurely_login_user");
if (screenName == null || screenName.isEmpty())
return null;
try {
long companyId = PortalUtil.getCompanyId(request);
User user = UserLocalServiceUtil.getUserByScreenName(companyId,
screenName);
return new String[] { String.valueOf(user.getUserId()),
user.getPassword(),
String.valueOf(user.isPasswordEncrypted()) };
} catch (Exception e) {
return null;
}
}
}
Регистрация класса автолога
Теперь наш хук должен зарегистрировать этот класс как процессор автологин. Это действительно легко.
Сначала отредактируйте файл docroot/WEB-INF/liferay-hook.xml
, добавив элемент portal-properties
со значением portal.properties
:
<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_1_0.dtd">
<hook>
<portal-properties>portal.properties</portal-properties>
</hook>
Теперь создайте файл с именем portal.properties
в docroot/WEB-INF/src
. Он должен содержать свойство с именем auto.login.hooks
, значение которого должно быть именем нашего класса:
auto.login.hooks=br.brandizzi.adam.liferay.insecure.InsecureAutoLogin
И это все. Разверните этот крючок, и ваш автолог будет работать.
Заключение
Как я уже сказал, вы не должны использовать такой небезопасный метод аутентификации. Слишком легко обойти это, получив даже административные разрешения! Однако, если вы выполните следующие шаги, у вас есть скелет, чтобы создать лучшую функцию автолога. Кроме того, я знаю, что некоторые люди действительно хотят сделать что-то вроде этого небезопасного метода "аутентификации", и иногда нам приходится приостанавливать наши суждения и просто помогать одному стрелять в одну ногу...
Исходный код этого проекта можно найти здесь, и вы можете скачать WAR здесь.