Возникли проблемы с реализацией логики «запомнить меня/оставаться в системе» [закрыто]JAVA

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

Сообщение Anonymous »

Я хотел бы реализовать функцию «запомнить меня» в моей очень простой системе на основе сервлетов. Ни Спринга, ни Широ, ничего. Я изо всех сил пытаюсь заставить это работать. На бумаге все кажется довольно простым. Чтобы начать, я использовал следующую ветку. Очень хорошая ветка «Запомни меня»
Насколько я понимаю, в связанной выше теме предлагалось 3 решения. 2 от BalusC и 3-е от (Илюа) Басина внизу темы.
Моя текущая попытка — попытаться реализовать решение 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;

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

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

/***********************************************************************
* @param request
* @param response
* @param username
* @param password
* @return
* @throws Exception
***********************************************************************/
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)
{
// In case of redirect there's no way to detect login success or failure
// The Location can be either the error page or the original page address.
// In the latter case it may still serve the login page again.
/*
String newcook = conn.getHeaderField("Set-Cookie");
if (newcook != null) {
// response.setHeader("Set-Cookie", newcook);
CookieCutter cc = new CookieCutter();
cc.addCookieField(newcook);
for (Cookie c : cc.getCookies()) {
response.addCookie(c);
}
}
*/
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();
}
}

/***********************************************************************
* @param params
* @return
* @throws Exception
***********************************************************************/
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();
}

/***********************************************************************
* @param request
* @param name
* @return
***********************************************************************/
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;
}

/***********************************************************************
* @param request
* @param response
* @param sName
***********************************************************************/
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);
}
}

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

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doGet(request, response);
}

}

@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 on;y 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 ... d-in-logic
Ответить

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

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

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

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

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