Same session in different browser tabs in jsp-servlet [duplicate] - java

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

Related

Java EE App don't print JSP file like jsp, but like HTML

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.

getSession().getAttribute("....") -> null

I created a signIn servlet:
#WebServlet(
name = "SignInServlet",
description = "check email & pass",
urlPatterns = {"/authorization_signin"}
)
public class SignInServlet extends javax.servlet.http.HttpServlet {
public SignInServlet(){
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws javax.servlet.ServletException, IOException {
request.setCharacterEncoding("UTF-8");
UserDataSet user = new UserDataSet();
SignInModel modelSignIn = new SignInModel();
user.setEmail(request.getParameter("email"));
user.setPassword(request.getParameter("password"));
user = modelSignIn.doSignIn(user);
if (request.getSession().getAttribute("loggedUser") == null) {
if (user != null) {
request.getSession().setAttribute("loggedUser", user); request.getRequestDispatcher("authorization.jsp").forward(request, response);
response.setStatus(HttpServletResponse.SC_OK);
} else {
request.setAttribute("errorMessage", "Email or password is incorrect");
request.getRequestDispatcher("index.jsp").forward(request, response);
response.setStatus(HttpServletResponse.SC_OK);
}
}
}
#Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException{
response.setContentType("text/html; charset=utf-8");
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
}
When user is signed in, servlet redirects him to "authorization.jsp"
<body>
<%
if (request.getSession().getAttribute("loggedUser") != null){
UserDataSet user = (UserDataSet) request.getSession().getAttribute("loggedUser");
System.out.println("In author :" + request.getSession().getAttribute("loggedUser"));
%>
<h1> Hello <%= user.getFirstName() %> <%= user.getLastName() %>!</h1>
<h2>AUTORIZED!</h2>
Log Out
<%
}
else {
%>
<h1>GO HOME</h1>
<%
}
%>
</body>
Then browser shows this page and data for signed in user
If write into URL "localhost:8080" and go to "index.jsp", then
again on "authorization.jsp"
Filter check session:
#WebFilter(filterName = "LoginFilter")
public class LoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest httpRequest = (HttpServletRequest) req;
HttpServletResponse httpResponse = (HttpServletResponse) resp;
System.out.println("Enter filter");
System.out.println("Filter session: " + httpRequest.getSession(false).getAttribute("loggedUser"));
UserDataSet user = (UserDataSet) httpRequest.getSession(false).getAttribute("loggedUser");
if (user != null) {
System.out.println("CHAIN");
chain.doFilter(req, resp);
} else {
httpResponse.sendRedirect("/");
System.out.println("Not signin");
}
}
public void init(FilterConfig config) throws ServletException {
}
}
And getSession().getAttribute("loggedUser") returns null
Why?
Next text:
If I signed in and servlet open "authorization.jsp", then try to go throw URL on any *.jsp where session will be checked and the result will be null
What's wrong?
My friend had help me found answer for this question in some answers on stackoverflow
If you put something in the session with request.getSession().setAttribute you have to read it from the session, not the request. Try <%= session.getAttribute("test") %>
Link to answer
I used
<%= request.getParameter("loggedUser") %>
For some reason I saw [1] in java logs when I used request.getSession().getAttribute("loggedUser") , I also observed in the same code that request.getParameter works, at least when values are passed by query strings and the "unchecked or unsafe operations" disappears from the log .
So seems to me that can be a solution for this question.
[1]
_index__jsp.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Java Servlets cant use session attribute in another servlet

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.

Session attributes getting lost

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

session does not invalidates

I'm trying to write a filter, which checks if user is logged in, and in case is not redirect him to login page. previously I had filter which actually did nothing -_- here it is, and with this filter everythig works ok, and session invalidates:
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession();
if (session == null || session.getAttribute("UserName") == null) {
String command = request.getParameter("command");
request.setAttribute("command", "login");
// String page = ConfigurationManager.getInstance().getProperty(
// ConfigurationManager.LOGIN_PAGE_PATH);
} else {
String username = (String) session.getAttribute("UserName");
UserRole role;
try {
role = UserDAOImpl.getUserRole(username);
session.setAttribute("role", role);
} catch (DAOTechnicException e) {
logger.error(e);
} catch (DAOLogicException e) {
logger.error(e);
}
}
chain.doFilter(req, res);
}
and when I invalidate session then it goes to (if session == null) block, and everything is ok.
but now I have another filter, here it is :
public class UserCheckFilter implements Filter {
static class FilteredRequest extends HttpServletRequestWrapper {
public FilteredRequest(ServletRequest request) {
super((HttpServletRequest) request);
}
public String getParameter(String paramName) {
String value = super.getParameter(paramName);
if(value!=null){
if (value.equals("login")) {
return value;
}
HttpSession session = super.getSession();
if (session == null || session.getAttribute("UserName") == null) {
value = "login";
}
}
return value;
}
}
/**
* Checks if user logged in and if not redirects to login page
*/
#Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("UserName") == null) {
if(request.getParameter("command")!=null){
String command = request.getParameter("command");
if(!command.equals("login")){
FilteredRequest filtrequest = new FilteredRequest(request);
String filteredvalue = filtrequest.getParameter("command");
chain.doFilter(filtrequest, res);
}else{
chain.doFilter(req, res);
}
}else{
chain.doFilter(req, res);
}
} else {
String username = (String) session.getAttribute("UserName");
UserRole role;
chain.doFilter(req, res);
try {
role = UserDAOImpl.getUserRole(username);
session.setAttribute("role", role);
} catch (DAOTechnicException e) {
logger.error(e);
} catch (DAOLogicException e) {
logger.error(e);
}
}
}
in which I wrap getParameter method and check if not logged in user is trying to go to user or admin pages. But when I invalidate session, it does not invalidates, i.e. all parameters are staying the same, and then in the filter where it checks if session != null, it's not null, and in line session.setAttribute("role", role); I get exception "session is already invalidated"
here's the method where i invalidate session :
if(request.getSession(false)!=null){
request.getSession().invalidate();
}
String page = ConfigurationManager.getInstance().getProperty(
ConfigurationManager.LOGIN_PAGE_PATH);
return page;
and in servlet U use
RequestDispatcher dispatcher = getServletContext()
.getRequestDispatcher(page);
dispatcher.forward(request, response);
and btw such things with invalidating session occurs only with second filter
p.s. sorry for probably stupid question, but I really don't know what's wrong,
so any suggestions would be appreciated.
I think this is because you're always calling chain.doFilter().
Per Oracle's docs...
A typical implementation of this method would follow the following
pattern:-
Examine the request
Optionally wrap the request object with a custom implementation to filter content or headers for input filtering
Optionally wrap the response object with a custom implementation to filter content or headers for output filtering
a) Either invoke the next entity in the chain using the FilterChain object (chain.doFilter()),
b) or not pass on the request/response pair to the next entity in the filter chain to block the request processing
Directly set headers on the response after invocation of the next entity in the filter chain.
In step 4, you probably want to do (b) - that is, instead of passing the request to the next filter in the chain, return the result to the user. I mean, it's an invalid session, so why bother trying to perform additional processing?

Categories