Es gibt Probleme bei der Implementierung der Logik „Angemeldet bleiben/angemeldet bleiben“.Java

Java-Forum
Anonymous
 Es gibt Probleme bei der Implementierung der Logik „Angemeldet bleiben/angemeldet bleiben“.

Post by Anonymous »

Ich würde gerne eine Erinnerungsfunktion in meine sehr einfachen Servlet-basierten Systeme implementieren und habe große Mühe, sie zum Laufen zu bringen. Auf dem Papier scheint es ziemlich einfach zu sein. Als Einstieg habe ich den folgenden Thread verwendet. Sehr schöner Remember Me-Thread
Soweit ich es verstanden habe, bot der oben verlinkte Thread drei Lösungen. 2 von BalusC und die dritte von (Ilyua) Basin am Ende des Threads.
  • Die erste von BalusC vorgeschlagene Lösung von Java 8 und höher konnte ich nicht verstehen :( Da ich den gesamten Arbeitsablauf nicht herausfinden konnte, wo die von ihm bereitgestellten Klassen eingefügt werden. Dem von ihm bereitgestellten Link zu einem vollständigen Beispiel zu folgen, hat mir leider nicht geholfen. :(
  • Ich habe dann die Lösung von (Ilyua) Basin ausprobiert, da ich bereits eine login.jsp-Seite habe, die dies tut, also dachte ich, dass es ein Problem wäre, dies programmgesteuert zu tun. In Wirklichkeit lieferte es jedoch immer einen 404-Antwortcode von Tomcat, und konnte ihn nicht umgehen. :(
  • Damit blieb BalusCs Lösung 2 für Java übrig 6/7. Hier stoße ich auf zwei Probleme. :( Problem eins ist die Sitzung. Der Filter wird während des Anmeldevorgangs dreimal aufgerufen. Wenn meine index.jsp-Seite eine geschützte Ressource „startup.jsp“ anfordert, wird der Filter aufgerufen, wobei die Sitzung null ist und alles rosig ist. Während dieses Aufrufs überprüfe ich das Cookie und den DB-Eintrag und wenn beide fehlen, leite ich den Benutzer zur Seite login.jsp weiter, um seine Anmeldeinformationen anzugeben. Der Benutzer gibt die Anmeldeinformationen an und der Filter wird erneut aufgerufen. Da ich im Filter sehe, dass wir von login.jsp kommen, leite ich den Aufruf an das Servlet weiter, das nicht null ist. Es erstellt also eine Zeile für diesen Benutzer mit einer eindeutigen Cookie-ID und fügt das Benutzerobjekt in die Sitzung ein Bei diesem dritten Aufruf ist die Sitzung zu meinem großen Entsetzen wieder null, was die gesamte Logik völlig durcheinander bringt.
  • Mein zweites Problem, das wahrscheinlich nicht mit den anderen zusammenhängt, ist die Cookie-Verwaltung. Manchmal ist mein Cookie gesetzt und manchmal nicht. Manchmal ist es jedoch nicht möglich, das Cookie zu löschen Cookie-Aufruf. :O
Offensichtlich fehlt mir etwas (oder viele Dinge), da diese Funktionalität an vielen, vielen Stellen erfolgreich implementiert wurde.

Code: Select all

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);
}
}
}
}

Code: Select all

@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);
}

}

Code: Select all

@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);
}
}

}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post