Я знаю, что это старый вопрос, но я наткнулся на него в своем собственном поиске для сканирования по траектории и нашел еще один хороший ответ, поэтому я добавляю его здесь.
Google Guava имеет объект ClassPath , который обеспечивает «наилучшее усилие» сканирование классов (на самом деле это все предложения утилиты сканирования классов). Поскольку Guava является широко принятой, тщательно укомплектованной библиотекой утилиты, это отличный вариант для проектов, которые либо (а) уже используют Guava, либо (b) нуждаются в стабильной библиотеке, на которую они могут положиться для сканирования пути к классам.
Если вы используете Java EE 8 или новее, поместите @RememberMe
в пользовательский HttpAuthenticationMechanism
а также RememberMeIdentityStore
.
@ApplicationScoped
@AutoApplySession
@RememberMe
public class CustomAuthenticationMechanism implements HttpAuthenticationMechanism {
@Inject
private IdentityStore identityStore;
@Override
public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext context) {
Credential credential = context.getAuthParameters().getCredential();
if (credential != null) {
return context.notifyContainerAboutLogin(identityStore.validate(credential));
}
else {
return context.doNothing();
}
}
}
public class CustomIdentityStore implements RememberMeIdentityStore {
@Inject
private UserService userService; // This is your own EJB.
@Inject
private LoginTokenService loginTokenService; // This is your own EJB.
@Override
public CredentialValidationResult validate(RememberMeCredential credential) {
Optional<User> user = userService.findByLoginToken(credential.getToken());
if (user.isPresent()) {
return new CredentialValidationResult(new CallerPrincipal(user.getEmail()));
}
else {
return CredentialValidationResult.INVALID_RESULT;
}
}
@Override
public String generateLoginToken(CallerPrincipal callerPrincipal, Set<String> groups) {
return loginTokenService.generateLoginToken(callerPrincipal.getName());
}
@Override
public void removeLoginToken(String token) {
loginTokenService.removeLoginToken(token);
}
}
Вы можете найти пример реального мира в Java EE Kickoff Application .
Если вы используете Java EE 6 или 7, homegrow - долгоживущий cookie для отслеживания уникального клиента и использования API-интерфейса Servlet 3.0 при условии, что он имеет программный вход HttpServletRequest#login()
, когда пользователь не вошел в систему, но файл cookie присутствует.
Это самый простой для достижения, если вы создаете другую таблицу БД со значением java.util.UUID
как ПК и идентификатором соответствующего пользователя как FK.
Предположим, что следующая форма входа:
<form action="login" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="checkbox" name="remember" value="true" />
<input type="submit" />
</form>
И следующее в doPost()
методе Servlet
, которое отображается на /login
:
String username = request.getParameter("username");
String password = hash(request.getParameter("password"));
boolean remember = "true".equals(request.getParameter("remember"));
User user = userService.find(username, password);
if (user != null) {
request.login(user.getUsername(), user.getPassword()); // Password should already be the hashed variant.
request.getSession().setAttribute("user", user);
if (remember) {
String uuid = UUID.randomUUID().toString();
rememberMeService.save(uuid, user);
addCookie(response, COOKIE_NAME, uuid, COOKIE_AGE);
} else {
rememberMeService.delete(user);
removeCookie(response, COOKIE_NAME);
}
}
(COOKIE_NAME
должно быть уникальным именем cookie, например "remember"
и COOKIE_AGE
должен быть временем в секундах, например 2592000
в течение 30 дней)
Вот как метод doFilter()
для Filter
, который отображается на re строковые страницы могут выглядеть так:
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
User user = request.getSession().getAttribute("user");
if (user == null) {
String uuid = getCookieValue(request, COOKIE_NAME);
if (uuid != null) {
user = rememberMeService.find(uuid);
if (user != null) {
request.login(user.getUsername(), user.getPassword());
request.getSession().setAttribute("user", user); // Login.
addCookie(response, COOKIE_NAME, uuid, COOKIE_AGE); // Extends age.
} else {
removeCookie(response, COOKIE_NAME);
}
}
}
if (user == null) {
response.sendRedirect("login");
} else {
chain.doFilter(req, res);
}
В сочетании с этими вспомогательными методами cookie (слишком плохо они отсутствуют в API сервлета):
public static String getCookieValue(HttpServletRequest request, String name) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
return cookie.getValue();
}
}
}
return null;
}
public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
cookie.setMaxAge(maxAge);
response.addCookie(cookie);
}
public static void removeCookie(HttpServletResponse response, String name) {
addCookie(response, name, null, 0);
}
Хотя UUID
чрезвычайно сложно использовать грубую силу, вы можете предоставить пользователю возможность заблокировать опцию «запомнить» на IP-адрес пользователя (request.getRemoteAddr()
) и сохранить / сравнить его в базе данных. Это делает его еще более надежным.
Также полезно заменить значение UUID
, когда пользователь изменил свой пароль.
Пожалуйста, обновите.
Вы не можете полностью войти в систему через HttpServletRequest.login (имя пользователя, пароль), так как вы не должны хранить как имя пользователя, так и пароль обычного текста в базе данных. Также вы не можете выполнить этот логин с хешем пароля, который сохраняется в базе данных. Однако вам нужно идентифицировать пользователя с маркером cookie / DB, но введи его в систему без ввода пароля с помощью пользовательского модуля входа (класс Java) на основе API-интерфейса Glassfish.
См. Следующие ссылки для получения дополнительной информации. подробности:
http://www.lucubratory.eu/custom-jaas-realm-for-glassfish-3/
Пользовательская безопасность механизм в Java EE 6/7 application
Обычно это делается следующим образом:
Когда вы регистрируете пользователя, вы также устанавливаете cookie на клиенте (и сохраняете значение cookie в базе данных), истекающее через определенное время (1-2 недель).
Когда приходит новый запрос, проверьте, существует ли определенный файл cookie, и если да, посмотрите в базу данных, чтобы узнать, соответствует ли она определенной учетной записи. Если он будет соответствовать, вы «свободно» войдете в эту учетную запись. Когда я говорю свободно, я имею в виду, что вы только позволяете этой сессии читать какую-то информацию и не писать информацию. Вам нужно будет запросить пароль, чтобы разрешить параметры записи.
Это все, что есть. Хитрость заключается в том, чтобы убедиться, что «свободный» логин не может нанести большой вред клиенту. Это несколько защитит пользователя от кого-то, кто схватит его, запомнит мне cookie и попытается войти в систему как он.
j_security_check
. Это новое в Servlet 3.0. См. Также «Программируемый вход». в учебнике JEE6: download.oracle.com/javaee/6/tutorial/doc/gjiie.html – BalusC 24 February 2011 в 02:52uuid
здесь неуместно, так как он не существует в таблице. Просто удалите все записи, связанные с идентификатором пользователя. – BalusC 24 February 2011 в 18:38