I am having a problem with a relativly easy thing. I am trying to do a simple program, where you can log in and log out using the session.
The session is created, but I am always getting forwarded to panel servlet and then to NoCorrectSession page. As if on login page the server saw isActive attribute, and then on panel page had not.
//class Login extends HttpServlet
private RequestDispatcher pageLogin, pagePanel, pageError; //defined in init()
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
String name = request.getParameter("name");
String isBeingRequested = request.getParameter("isBeingRequested");
if (session.getAttribute("isActive") != null) {
//user has been logged in before, redirect him
pagePanel.forward(request, response);
} else if (isBeingRequested != null) {
//user has entered data into the login page and submitted it
if (name.length() == 0) {
//user has not stated his name
pageError.forward(request, response);
} else {
//otherwise access is granted and account created
session.setAttribute("isActive", "yes"); //setting session to active
pagePanel.forward(request, response);
}
} else {
//neither of these? user just entered the login screen
pageLogin.forward(request, response);
}
}
//class Panel extends HttpServlet {
private RequestDispatcher pageNoCorrectSession;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
//session has expired or never was started
if (session.getAttribute("isActive") == null) {
pageNoCorrectSession.forward(request, response);
//session valid
} else {
//logged in - do stuff
}
After digging in the project it turned out I've not made a mistake in these servlets, but in HTML code causing submitting a form directly to the panel servlet (and not creating the account object in the process). I know it is silly, but it was a great lesson. Expect the unexpected :P
Related
I have project maven web-application. I have a few JSP files with HTML code and JSP tags. I have a connection in the local database and a few servlets.
Problem is that when I logged in to the app, I want to print a welcome message for the logged user.
This is the tag which should display a welcome message:
<div class="hello-text"><h1>Hello <span>${sessionScope.user_name}</span>. This is yours stats:</h1></div>
When I logged in the only text that I have is "Hello ${sessionScope.user_name}. This is your stats:
This is my servlet code for logging in:
#WebServlet("/login")
public class UserLoginServlet extends HttpServlet {
private static final long serialVersionUID = 2717450811223035557L;
private UserRepository userRepository = new UserRepositoryBean();
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
String login = req.getParameter("login");
String password = req.getParameter("password");
PrintWriter writer = resp.getWriter();
if (login == null | login.isEmpty() | password == null | password.isEmpty()) {
writer.write("ERROR");
return;
} else {
if (userRepository.validateUser(login, password)) {
HttpSession session = req.getSession();
session.setAttribute("user_name", login);
resp.sendRedirect("profile.jsp");
} else {
req.setAttribute("error", "Invalid login or password. Try again.");
req.getRequestDispatcher("login.jsp").forward(req, resp);
}
}
writer.close();
}
}
Why I don't have a message, for example, Hello Admin. This is your stats:?
I always have Hello ${sessionScope.user_name}. This is your stats:...
A sendRedirect should not be mixed by other output of some page.
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String login = req.getParameter("login");
String password = req.getParameter("password");
if (login.isEmpty() || password.isEmpty()) {
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.write("ERROR");
return;
}
if (userRepository.validateUser(login, password)) {
HttpSession session = req.getSession();
session.setAttribute("user_name", login);
resp.sendRedirect("profile.jsp");
} else {
req.setAttribute("error", "Invalid login or password. Try again.");
req.getRequestDispatcher("login.jsp").forward(req, resp);
}
}
The first if could be done by the validation - as empty input happens often - by a nice error message reposted to the same form with already done input saved.
If the JSP comes as HTML, then ensure it has a valid servlet mapping.
Also the JSP better should not be placed in a public directory, but maybe under WEB-INF/jsps/ or such.
I am unable to close my session using session.invalidate() in my logout method please help!
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
response.getWriter().println("<h3><a href='/assign2'>Logged out Successfully</a></h3>");
HttpSession session = request.getSession(false);
if(session!=null)
session.invalidate();
}
the username does not get written to null at all
here's my welcome page to where i am redirecting it
HttpSession session=request.getSession(false);
if(session!=null)
{
if((request.getSession().getServletContext().getAttribute("userid")) != null)
{
username = request.getSession().getServletContext().getAttribute("userid").toString();
}
}
System.out.println(username);
The logoff page is OK, but in the welcome page you are mixing concepts:
Altough the execution of session.invalidate does unbind all the bound attributes, you are retrieving attribute userid from the ServletContext, not the Session. Besides, note that request.getSession() creates a new session if necessary.
The coherent way to store and retrieve attributes would be through the HttpSession object:
HttpSession session=request.getSession(false);
if(session!=null)
{
if((session.getAttribute("userid")) != null)
{
username = session.getAttribute("userid").toString();
}
}
System.out.println(username);
I've a filter used for the login. It performs a textual checking, on fields "Username" and "Password". If and only if the textual checking is correctly done the request goes to the Servlet. This latter performs the control that has to interact with the Database. Is this chain correct?
Preface: I gather you're using homegrown login instead of container managed login. For all ways, see How to handle authentication/authorization with users in a database?
The filter (the interceptor) shouldn't check the validity of the username/password combo. That's the responsibility of the servlet (the controller).
The filter should merely check if the user is logged-in or not (usually by just checking the presence of a session attribute) and then continue the request or block it by redirecting back to the login page.
#WebFilter("/*")
public class LoginFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/login";
boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean loginRequest = request.getRequestURI().equals(loginURI);
if (loggedIn || loginRequest) {
chain.doFilter(request, response);
} else {
response.sendRedirect(loginURI);
}
}
// ...
}
The servlet should collect the submitted data, find the associated User in database and if found then store it as a session attribute and then redirect to the home page, else redisplay the form with validation errors.
#WebServlet("/login")
public class LoginServlet extends HttpServlet {
#EJB
private UserService userService;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
Map<String, String> messages = new HashMap<String, String>();
if (username == null || username.isEmpty()) {
messages.put("username", "Please enter username");
}
if (password == null || password.isEmpty()) {
messages.put("password", "Please enter password");
}
if (messages.isEmpty()) {
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath() + "/home");
return;
} else {
messages.put("login", "Unknown login, please try again");
}
}
request.setAttribute("messages", messages);
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
}
See also:
Our servlet-filters wiki page
Our servlets wiki page
I am trying to get my first servlets to work. I have found some similar problems and solutions to them, but it´s not excatly what I would like to do.
This is my login servlet:
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String username=request.getParameter("username");
String password=request.getParameter("password");
if(LoginValidator.validate(username, password)){
HttpSession session = request.getSession();
session.setAttribute("user", username);
session.setMaxInactiveInterval(30*60);
Cookie sessionCookie = new Cookie("sessionKuki", username);
sessionCookie.setMaxAge(30*60);
response.addCookie(sessionCookie);
RequestDispatcher rd=request.getRequestDispatcher("paste.jsp"); //INSTEAD of paste.jsp I would like to get session attribute called uri I set in filter. BUT I when I try to use get attribute, Eclipse says there is no attribute called URI.
rd.forward(request,response);
}
else{
out.print("Sorry username or password error");
RequestDispatcher rd=request.getRequestDispatcher("login.html");
rd.include(request,response);
}
out.close();
}
}
And there is filter that I use to redirect to login page, when user is not signed in:
public class SessionFilter implements Filter{
// private ServletContext context;
public void init(FilterConfig filterConfig) throws ServletException {
//this.context = filterConfig.getServletContext();
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI(); //THERE IS uri of the site from where the user gets redirected to login page
HttpSession session = req.getSession(false);
session.setAttribute("uri", uri); // HERE I TRY to set uri to session attribute. My intention is to use that uri in my login servlet
if(uri.endsWith(".css")) {
chain.doFilter(request, response);
return;
}
if(uri.endsWith(".js")) {
chain.doFilter(request, response);
return;
}
if(session == null && !(uri.endsWith("login.html") || uri.endsWith("login") || uri.endsWith("forgot.jsp") || uri.endsWith("signup.jsp"))){
res.sendRedirect("login.html");
System.out.print("redirecting to login");
}else{
chain.doFilter(request, response);
}
}
public void destroy() {
}
}
Is it even possible, what I am trying to do? How to do it? Is there a better way to do it? I dont want to mix html and script. My intention is that, when user comes to a pages, and trys to get access to somewhere, he is redirected to login page. And after he logs in, he should be redirected to the page he wanted to go at the beginning.
Not sure if this would work but please try doing your filter like this:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();
HttpSession currentSession = req.getSession(false);
if(uri.endsWith(".css")) {
chain.doFilter(request, response);
return;
}
if(uri.endsWith(".js")) {
chain.doFilter(request, response);
return;
}
if(currentSession == null && !(uri.endsWith("login.html") || uri.endsWith("login") || uri.endsWith("forgot.jsp") || uri.endsWith("signup.jsp"))){
HttpSession newSession = req.getSession();
newSession.setAttribute("uri", uri);
res.sendRedirect("login.html");
System.out.print("redirecting to login");
}else{
chain.doFilter(request, response);
}
}
What i did was create a new session in the filter if the session is null.
I have created a login page for mock of hotel administrator. Now I want to add session time function to it. In other words, let's say the user leaves the computer (he is still logged into the admin webpage) for like 10 minutes or so. Then when he come back, I want to end the current session and then redirect to login page (this is more secured and his personal info would never be lost!).
How do I make that happen?
public class LoginServlet extends SpringInjectedServlet {
#Autowired
private LoginService loginService;
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String id = req.getParameter("id");
String password = req.getParameter("password");
String error = null;
//code for checking correct input
}
// mock
private boolean check(String id, String password) {
return loginService.authenticate(id, password);
}
#Override
public void init() throws ServletException {
System.out.println("LoginServlet");
}
}
Use Authentication Filters to check for Session in every request like
HttpSession session = request.getSession();
if (session == null || session.getAttribute("username") == null) {
// Forward the control to login.jsp if authentication fails or session expires
request.getRequestDispatcher("/login.jsp").forward(request,
response);
}
This will check for login username from session for every request if its null or the session expired ,it will redirect to login page.
Add this in web.xml
<session-config>
<session-timeout>5</session-timeout>
</session-config>
Check it here.
After you've verified the credentials, set a session variable for the userid, and to set the session expiration:
session.setMaxInactiveInterval(600); //600 secs = 10 mins
session.setAttribute("userid", userid);
Then at the top of all your JSPs and in all your servlets you do something like:
String userid = (String)session.getAttribute("userid");
if(userid==null)
{
response.sendRedirect("login.jsp");
return; //the return is important; forces redirect to go now
}
After the 10 minutes have elapsed, this will only redirect the user to the login page if they click a link, refresh, or somehow go to another page. If they just leave the page sitting there open, it will still display. To change that you would have to involve Javascript somehow.