Реализация логики «запомнить меня/оставаться в системе» в сервлетеJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Реализация логики «запомнить меня/оставаться в системе» в сервлете

Сообщение Anonymous »

Я хотел бы реализовать функцию «запомнить меня» в моей очень простой системе на основе сервлетов. Ни Спринга, ни Широ, ничего. Я изо всех сил пытаюсь заставить это работать.
На бумаге это кажется довольно простым. Чтобы начать, я использовал следующую ветку \[Очень хорошая ветка "Запомнить меня"\](Как реализовать функцию "Оставаться в системе" при входе пользователя в веб-приложение)
Насколько я понимаю, в теме, связанной выше, предложено 3 решения: 2 от BalusC и третье от (Ilyua) Basin в нижней части ветки.
Моя текущая попытка — реализовать решение 2 от BalusC для Java 6/7. Поскольку мне не удалось заставить работать остальные 2.
Здесь я столкнулся с 2 проблемами. Однако я упомяну только одну проблему, чтобы мой вопрос не закрылся.
Похоже, что фильтр вызывается 3 раза во время процесса входа в систему. Когда моя страница index.jsp запрашивает защищенный ресурс /jsp/startup.jsp, фильтр вызывается с нулевым сеансом, и все в порядке.
Во время этого вызова я проверяю файл cookie и запись в БД, а также их отсутствие. Я пересылаю пользователя на страницу login.jsp для первого ввода учетных данных.
Пользователь указывает учетные данные и отправляет форму; фильтр вызывается второй раз. Увидев в фильтре, что мы исходим из файла login.jsp, я пересылаю вызов сервлету, который обрабатывает страницу входа. Теперь этот сервлет имеет ненулевой сеанс.
Он создает файл cookie, вставляет в базу данных строку для этого пользователя с уникальным идентификатором файла cookie и сохраняет объект пользователя в сеансе. В конце сервлета я пересылаю пользователя на страницу start.jsp, которую он запросил для начала. Это еще раз вызывает вызов фильтра, уже в третий раз, и тут все ломается. В этом третьем вызове фильтра сеанс снова становится нулевым, к моему большому шоку и разочарованию, что полностью портит всю логику.
Очевидно, что я что-то упускаю (или многое), поскольку эта функциональность была реализована во многих, многих местах и ​​успешно. Хотелось бы понять, чего мне не хватает.
public class MyServletFilter extends SecurityParentServlet implements Filter
{
protected static final Logger logger = Logger.getLogger(MyServletFilter.class);

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fchain)
throws IOException, ServletException
{
logger.debug("MyServletFilter was called");
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
String sUserName = request.getParameter("username");
if ((sUserName != null) && (sUserName.length() > 0))
{
// The user is logging in so we should not be here
fchain.doFilter(req, resp);
return;
}
// If the user is logged in and in the session then send them along
HttpSession session = request.getSession(false);
if ((session != null) && (session.getAttribute("user") != null))
{
fchain.doFilter(req, resp);
return;
}
else
{
// Try to auto log the user in. They must have a cookie,
// be in the DB and DB record must not be expired
String uuid = getCookieValue(request, COOKIE_NAME);
logger.debug("MyServletFilter cookie value = "+uuid);
RememberMeUser rmUser = null;
if (uuid != null)
{
rmUser = DBHandler.getRememberUser(uuid);
logger.debug("MyServletFilter rmUser from DB = "+rmUser);
if (rmUser != null) {
request.login(rmUser.getAccount(), rmUser.getPassword());
session.setAttribute("user", rmUser);
logger.debug("MyServletFilter adding the cookie");
addCookie(response, uuid); // Extends age.
logger.debug("User is "+request.getRemoteUser());
} else {
logger.debug("MyServletFilter deleting the cookie");
removeCookie(response);
}
}
if (rmUser == null) {
goToLogin(request, response);
} else {
fchain.doFilter(req, resp);
}
}
}
}

@WebServlet("/SecurityParentServlet")
public class SecurityParentServlet extends HttpServlet
{
public static final String COOKIE_NAME = "rememberme";
public static final int COOKIE_AGE = 30 * 86400;

public static void addCookie(HttpServletResponse response, String value)
{
Cookie cookie = new Cookie(COOKIE_NAME, value);
cookie.setPath("/");
cookie.setMaxAge(COOKIE_AGE);
response.addCookie(cookie);
}

public static void removeCookie(HttpServletResponse response)
{
Cookie cookie = new Cookie(COOKIE_NAME, null);
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
}

public static boolean jSecurityCheck(HttpServletRequest request,
HttpServletResponse response,
String username,
String password)
throws Exception
{
HashMap formParams = new HashMap();
formParams.put("j_username", username);
formParams.put("j_password", password);
byte[] postData = getDataString(formParams).getBytes( StandardCharsets.UTF_8 );
int postDataLength = postData.length;
// TODO: detect container http listener has SSL/TLS enabled
// (request.isSecure() unreliable due to possible offload)
// String s = "http://" + request.getLocalAddr() + ":" + request.getLocalPort()
// + request.getContextPath() + "/j_security_check";
String s = "http://localhost:8080/j_security_check";
URL url = new URL(s);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
try {
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");

String PROP = "sun.net.http.allowRestrictedHeaders";
if (!"true".equals(System.getProperty(PROP))) {
request.getServletContext().log("must set to true: " + PROP);
}
System.out.println(System.getProperty(PROP));
System.out.println(request.getHeader("Host"));
System.out.println(request.getHeader("Cookie"));
conn.setRequestProperty("Host", request.getHeader("Host"));

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
conn.setRequestProperty("charset", "utf-8");
conn.setRequestProperty("Cookie", request.getHeader("Cookie"));
OutputStream wr = conn.getOutputStream();
try {
wr.write(postData);
} finally {
wr.close();
}
// Request sent wait for response
int code = conn.getResponseCode();
String location = null;
if (code == 301 || code == 302 || code == 303 || code == 307 || code == 308)
{
location = conn.getHeaderField("Location");
if (location != null)
{
response.sendRedirect(location);
return true;
}
}
else
{
// if getInputStream() succeeds, then http 200 or such
// meaning login failure (Tomcat)
conn.getInputStream().close();
return false;
}
throw new ServletException("Unexpected j_security_check response " + code + " Location: " + location);
}
finally
{
conn.disconnect();
}
}

private static String getDataString(HashMap params)
throws Exception
{
StringBuilder result = new StringBuilder();
boolean first = true;
for(HashMap.Entry entry : params.entrySet()){
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}

public static String getCookieValue(HttpServletRequest request, String name)
{
String sValue = null;
Cookie[] cookies = request.getCookies();
if (cookies != null)
{
for (Cookie cookie : cookies)
{
if (name.equals(cookie.getName()))
{
sValue = cookie.getValue();
}
}
}
return sValue;
}

protected void forward(HttpServletRequest request,
HttpServletResponse response,
String sName)
{
try
{
response.reset();
RequestDispatcher dispatcher = request.getRequestDispatcher("/ewa/"+sName+".jsp");
if (dispatcher != null)
dispatcher.forward(request, response);
}
catch (Exception e)
{
// logger.error(e.getMessage(), e);
}
}

protected void goToLogin(HttpServletRequest request,
HttpServletResponse response)
{
try
{
response.reset();
RequestDispatcher dispatcher = request.getRequestDispatcher("Login1.jsp");
if (dispatcher != null)
dispatcher.forward(request, response);
}
catch (Exception e)
{
// logger.error(e.getMessage(), e);
}
}

@WebServlet("/ProcessLogin")
public class ProcessLogin extends SecurityParentServlet
{
protected static final Logger logger = Logger.getLogger(ProcessLogin.class);

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String sUserName = request.getParameter("username");
String sPassword = request.getParameter("password");
String sRememberMe = request.getParameter("remember_me");
RememberMeUser rmUser = new RememberMeUser();

if (sRememberMe != null)
{
// 1.Generate the unique Id to store in the cookie
String uuid = UUID.randomUUID().toString();
rmUser.setUniqueId(uuid);
// 2. Add the cookie
addCookie(response, uuid);
// 3. Save the user credentials in the DB with cookie id as the index
if (DBHandler.isRememberUserInDB(sUserName))
DBHandler.updateRememberMeUser(sUserName, uuid, sPassword);
else
DBHandler.insertRememberMeUser(uuid, sUserName, sPassword);
}
else
{
// Delete cookie and table entry
removeCookie(response);
DBHandler.deleteRememberMeUser(sUserName);
}
// Last step Log the user in
try
{
request.login(sUserName, sPassword);
rmUser.setAccount(sUserName); // For now we wil leave th PW unset and fetch from the DB if needed
// logger.debug("User is "+request.getRemoteUser()); // Sadly this only works at the time login method is called any subsequent calls makes this value disappear, hence we store the user in the session
HttpSession session = request.getSession(false);
session.setAttribute("user", rmUser); // Login.
// if (jSecurityCheck(request, response, sUserName, sPassword))
forward(request, response, "index");
}
catch (Exception e)
{
logger.error("Exception trying to login "+sUserName, e);
// Logging the user in automatically failed so send them to the Login screen
goToLogin(request, response);
}
}

}


Подробнее здесь: https://stackoverflow.com/questions/798 ... -a-servlet
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»