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.
Related
I stuck up with doFilter of HttpServletRequest.
Im trying to replace new URL for that request.
My code is as follows:
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpRes = (HttpServletResponse) res;
//If request resources ==> Continue
if(httpReq.getContextPath().startsWith(httpReq.getContextPath()+"/resources")){
chain.doFilter(req, res);
return;
}
HttpSession session = httpReq.getSession();
EmployeeDTO currentEmployee =(EmployeeDTO)session.getAttribute("currentEmployee");
//If dont have session ==> Return login page
if(currentEmployee == null){
String requestURI = "";
requestURI = httpReq.getRequestURI().replace(httpReq.getRequestURI(), httpReq.getContextPath()+ "/login");
System.out.println(requestURI);
//httpRes.reset();
//httpRes.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
//httpRes.setHeader("Location", requestURI);
httpRes.sendRedirect(requestURI);
chain.doFilter(req, res);
return;
}
chain.doFilter(req, res);
return;
}
But the code above is still not working. How can i do for this?
Thanks in advance!
Why do you have to do a chain.doFilter() after setting a redirect response?
private FilterConfig filterConfig;
public void init(FilterConfig config) throws ServletException {
this.filterConfig = config;
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpRes = (HttpServletResponse) res;
HttpSession session = httpReq.getSession();
boolean requestResources = false;
//If request resources ==> Continue
if(httpReq.getContextPath().startsWith(httpReq.getContextPath()+"/resources")){
requestResources = true;
}
if(session != null){
EmployeeDTO currentEmployee =(EmployeeDTO)session.getAttribute("currentEmployee");
}
if(requestResources || currentEmployee != null){
chain.doFilter();
}else if(currentEmployee == null){
String loginURI = //hardcode the loginURI here.
httpRes.sendRedirect(loginURI);
/*alternatively use the following to do an internal forward rather than a redirect
RequestDispatcher rd = filterConfig.getServletContext().getRequestDispatcher(loginURI); //here the loginURI path should not have the context in the url.
rd.forward(servletReq, response);
*/
}
}
I have also refactored your code to remove the redundant and multiple 'return' statements
I have an authentication filter for my web app, and it successfulyl loads up the css for all the web pages after logging in, except for three pages the homepage(index) the about us page(about) and the register page(register). For some reason I cannot figure out why my filter is not deciding to load up the css for those three pages but for the other pages it works, I've checked the jsp files for all the pages and cant spot whats wrong.
I was told I had to fix something in my doFilter method with the excludeURLs but I'm still confused.
Here is my doFilter:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpSession session = httpReq.getSession(false); // if the fail login it doesnt create a session
if (session != null && session.getAttribute("user") == null && !excludeURLs.contains(httpReq.getServletPath()) ){
RequestDispatcher rd = httpReq.getRequestDispatcher("login.jsp");
rd.forward(request, response);
return;
}
chain.doFilter(request, response);
}
And here is the init method where I exclude specific URLs:
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("AuthenticationFilter Initiated...");
//Pages/Servlet
excludeURLs.add("/login");
excludeURLs.add("/login.jsp");
excludeURLs.add("/index");
excludeURLs.add("/index.jsp");
excludeURLs.add("/about");
excludeURLs.add("/about.jsp");
excludeURLs.add("/register");
excludeURLs.add("/signup.jsp");
//Images
excludeURLs.add("/Images");
excludeURLs.add("/css");
excludeURLs.add("/js");
}
Assuming:
Your css files to have the extension ".css",
Unauthenticated access to css files isn't an issue for your you/your organization, a quick fix would be:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpSession session = httpReq.getSession(false); // if the fail login it doesnt create a session
String path= httpReq.getRequestURI();
if(path.endsWith(".css")){
chain.doFilter(request,response);
return;
}
if (session != null && session.getAttribute("user") == null && !excludeURLs.contains(httpReq.getServletPath()) ){
RequestDispatcher rd = httpReq.getRequestDispatcher("login.jsp");
rd.forward(request, response);
return;
}
chain.doFilter(request, response);
}
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
*#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("INTERCEPTING---");
if(request !=null && request.getParameter("email")!=null){
System.out.println("session is NOT null------");
session = request.getSession();
session.setAttribute("user", request.getParameter("email"));
}else{
try{
if (session==null){
System.out.println("session lost");
}
}catch(IllegalStateException exception){
System.out.println("session expired");
"redirect:http://localhost:8080/web/authservice/fail";
/this is the redirection that i used, and i tried model and view as well but yet it does not work/
}
}
return true;
}
/*in the above method how should I redirect. Its not redirecting...............
Im unable to redirect the after the session expired it gives me a response commit exception. I ve been trying for hours no solution
Please provide a suitable solution */
Use a servlet filter instead, (place it according to you intercepet requirement in your web.xml).
public class CustomRequestFilter implements Filter {
WebApplicationContext springContext;
#Override
public void init(FilterConfig filterConfig) throws ServletException {
springContext = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
}
#Override
public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException, LicenseException {
HttpServletRequest request = (HttpServletRequest) req;
if (XXX) {
//forward or redirect as per requirement
request.getRequestDispatcher("/WEB-INF/jsp/errors/SystemError.jsp").forward(request, response);
}
chain.doFilter(request, response);
}
}
I am working on session management using filters i have written method and using managedbean annotation i'm trying to send the validation success to filter .
#ManagedBean(name = "customer")
#SessionScoped
public class CustomerBean implements Serializable{
public String checkValidCustomer(){
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
HttpSession session = request.getSession(true);
Customer cust = new Customer();
cust.setUsername(getUsername());
cust.setPassword(getPassword());
String returnValue = customerBo.checkValidCustomer(cust);
if(returnValue == "success"){
session.setAttribute("customer", returnValue);
}
else
{
session.setAttribute("customer", null);
}
return returnValue;
and i'm getting succes in retunValue string so i tried to pass as value to managedBean annotation .and myfilter code is like.
#WebFilter("/faces/*")
public class LoginFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String cust = (String) req.getSession().getAttribute("customer");
if (cust != null && cust.equals("success")) {
chain.doFilter(request, response);
} else {
resp.sendRedirect(req.getContextPath() + "/faces/default.xhtml");
}
}
I'm getting null value for String cust and when i open the page for login it shows This webpage has a redirect loop.Can you please tell where i'm doing wrong..
try this...
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
System.out.println("Inside the filter.............." );
HttpSession session = request.getSession();
User u = null;
if(session.getAttribute("customer")!=null){
u = (User) session.getAttribute("customer");
}
if (u!= null)
{
System.out.println("user does exits.." + u.getUname() );// u can see who was logged here
chain.doFilter(req, resp);
}else{
System.out.println("user does exits..");
}