Redirect to a JSP page after login using AJAX - ajax

I have a login.jsp page where users type in username and password. Username and password are sent to the server using ajax ($.post). When the authentication is complete, I want to redirect user to an index.jsp page.
js:
function Login()
{
var traderName = document.getElementById('username').value;
var traderPass = document.getElementById('password').value;
//SetLoginLoading();
data = {action:'login',username:traderName,password:traderPass};
$.post('TraderServlet',$.param(data),function(response){
});
return false;
}
Servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
....
login(request, response);
....
}
private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
String name = request.getParameter(PARAMETER_NAME);
String pass = request.getParameter(PARAMETER_PASS);
traderBean.login(name, pass);
response.sendRedirect("index.jsp");
}
I tried to use response.sendRedirect() but it does not work. Should I use jQuery to redirect user using ajaxCallback ?
Thank you.

In general, if you are just going to redirect anyway, there is really no point in using AJAX as you can accomplish this by just having the servlet handle directly from the form.
To your question, first check the url pattern of your servlet. Make sure it is actually being called. If so, then if it has a url pattern like
/TraderServlet
Then it expects index.jsp to be also in the root folder under Web. It could be that you are simply not redirecting to where you are expecting to go.
One way to check is (if you're in Chrome) use the debugger tools (F12 on Windows/Nix, Ctrl-Shift-I on Macs), and see what error it is giving.

Related

How to send body data within a redirect using Spring Security AuthenticationFailureHandler?

I would like to provide detailed information about a failed login attempt.
Thymleaf shall display regarding information as well as prefill the login form with already given values like email or username. I don't want to send these information as url parameters. From my understanding I need a POST request to the login url.
How can I achieve this using an AuthenticationFailureHandler, and is this even doable without implementing the login process completely manually?
At the moment, all I have is this:
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
#Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception) throws IOException {
String email = request.getParameter("email");
String password = request.getParameter("password");
/* How to make the response POST including data for Thymeleaf? */
redirectStrategy.sendRedirect(request, response, "/login");
}
}
Many thanks for any information

How to set, get and validate sessions in JSF like PHP $_SESSION[''] [duplicate]

I would like to block the access of some page even if the user knows the url of some pages.
For example, /localhost:8080/user/home.xhtml (need to do the login first) if not logged then redirect to /index.xhtml.
How do that in JSF ? I read in the Google that's needed a filter, but I don't know how to do that.
You need to implement the javax.servlet.Filter class, do the desired job in doFilter() method and map it on an URL pattern covering the restricted pages, /user/* maybe? Inside the doFilter() you should check the presence of the logged-in user in the session somehow. Further you also need to take JSF ajax and resource requests into account. JSF ajax requests require a special XML response to let JavaScript perform a redirect. JSF resource requests need to be skipped otherwise your login page won't have any CSS/JS/images anymore.
Assuming that you've a /login.xhtml page which stores the logged-in user in a JSF managed bean via externalContext.getSessionMap().put("user", user), then you could get it via session.getAttribute("user") the usual way like below:
#WebFilter("/user/*")
public class AuthorizationFilter implements Filter {
private static final String AJAX_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<partial-response><redirect url=\"%s\"></redirect></partial-response>";
#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 loginURL = request.getContextPath() + "/login.xhtml";
boolean loggedIn = (session != null) && (session.getAttribute("user") != null);
boolean loginRequest = request.getRequestURI().equals(loginURL);
boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
boolean ajaxRequest = "partial/ajax".equals(request.getHeader("Faces-Request"));
if (loggedIn || loginRequest || resourceRequest) {
if (!resourceRequest) { // Prevent browser from caching restricted resources. See also https://stackoverflow.com/q/4194207/157882
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
}
chain.doFilter(request, response); // So, just continue request.
}
else if (ajaxRequest) {
response.setContentType("text/xml");
response.setCharacterEncoding("UTF-8");
response.getWriter().printf(AJAX_REDIRECT_XML, loginURL); // So, return special XML response instructing JSF ajax to send a redirect.
}
else {
response.sendRedirect(loginURL); // So, just perform standard synchronous redirect.
}
}
// You need to override init() and destroy() as well, but they can be kept empty.
}
Additionally, the filter also disabled browser cache on secured page, so the browser back button won't show up them anymore.
In case you happen to use JSF utility library OmniFaces, above code could be reduced as below:
#WebFilter("/user/*")
public class AuthorizationFilter extends HttpFilter {
#Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain) throws ServletException, IOException {
String loginURL = request.getContextPath() + "/login.xhtml";
boolean loggedIn = (session != null) && (session.getAttribute("user") != null);
boolean loginRequest = request.getRequestURI().equals(loginURL);
boolean resourceRequest = Servlets.isFacesResourceRequest(request);
if (loggedIn || loginRequest || resourceRequest) {
if (!resourceRequest) { // Prevent browser from caching restricted resources. See also https://stackoverflow.com/q/4194207/157882
Servlets.setNoCacheHeaders(response);
}
chain.doFilter(request, response); // So, just continue request.
}
else {
Servlets.facesRedirect(request, response, loginURL);
}
}
}
See also:
Our Servlet Filters wiki page
How to handle authentication/authorization with users in a database?
Using JSF 2.0 / Facelets, is there a way to attach a global listener to all AJAX calls?
Avoid back button on JSF web application
JSF: How control access and rights in JSF?
While it's of course legitimate to use a simple Servlet filter, there are alternatives like
Spring Security
Java EE Security
Apache Shiro

Spring Security login with Ajax and success handler

I am working on letting user login to system using Ajax and with help of Spring security,As of now everything is working fine and as expected.
On Successful authentication, I am calling a SuccessHandler to do some post authentication work.
I need to pass some information (OK status or something like ) back to the calling method in my JSP page so as I can do other work in my JSP page.
One option is to add following code in onAuthenticationSuccess method
#Override
public void onAuthenticationSuccess(final HttpServletRequest request,final
HttpServletResponse response, final Authentication authentication) throws
IOException, ServletException {
// work done
try{
response.getWriter().print("SUCCESS");//return "SUCCESS" string
response.getWriter().flush();
}
catch(IOException e){
}
}
Though that will do work, but is there any other way or alternate to do it in good way or this approach is good enough?

difference between Spring mvc redirect and general jsp name return

Please consider these code snippets
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
return new ModelAndView("redirect:DummyRedirectPage.htm");
}
and
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
return new ModelAndView("somejsp");
}
Can anyone tell me the difference between the two? In both the cases the handler method is navigating the flow to a view page.
With the first one user will receive HTTP 302 response to redirect into DummyRedirectPage.htm. If the handler was mapped to a POST method, this will force user to perform GET to DummryRedierctPage.htm
On the second one your view resolver will resolve "somejsp" into an actual view. No HTTP 302 response is given to user.
Please read about PRG (Post Redirect Get) design pattern to find out why this matters.

Flash attributes in Spring MVC 3.1 not visible to redirected JSP

I am using Spring 3.1's new Flash Attribute support to set flash attributes on a RedirectAttributes object in a Controller and then invoking a redirect. That redirect request is in turn caught by a filter which then sends it on its merry way to the JSP that it's intended for. The problem: I can't see the flash attributes either from within the filter's doFilter() method or from the JSP. Non-flash (URL) attributes make it just fine.
Controller that does the redirect:
#RequestMapping("/pages/login")
public String login (HttpServletRequest request, Map<String, Object> model, RedirectAttributes redirectAttributes) {
model.put("userId", "batman");
String redirectUrl = request.getParameter("redirectUrl");
if (redirectUrl != null) {
redirectAttributes.addAttribute("attr1","ababab");
redirectAttributes.addFlashAttribute("flashAttr1", "flashflash");
for (Iterator<String> iterator = model.keySet().iterator(); iterator.hasNext();) {
String key = iterator.next();
redirectAttributes.addFlashAttribute(key, model.get(key));
}
return "redirect:"+redirectUrl;
} else {
return "pages/login";
}
}
The filter which picks up the redirect doesn't do anything interesting in this case:
public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
//if (httpRequest.getSession().getAttribute("userId") == null) {
//...do some stuff here which invokes controller above as well as the redirect
//} else {
chain.doFilter(request, response);
//}
}
The page that gets redirected to following the filter:
...
<title>Test Web App 1</title>
</head>
<body>
<p>Flash attribute: <c:out value="${flashAttr1}"/></p>
<p>Welcome <c:out value="${userId}"/>!</p>
</body>
</html>
Neither flashAttr1 nor userId end up being populated in the page. The attr1 non-flash attribute the controller set does appear in the URL params of the page, so that seems to work.
Here is some output from log4j after I set springfamework.web to DEBUG:
19:15:44,406 DEBUG http-8080-1 view.ContentNegotiatingViewResolver:494 - Returni
ng redirect view [org.springframework.web.servlet.view.RedirectView: name 'redir
ect:http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp';
URL [http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp]]
19:15:44,406 DEBUG http-8080-1 servlet.DispatcherServlet:1155 -
Rendering view [org.springframework.web.servlet.view.RedirectView: name
'redirect:http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp';
URL [http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp]] in
DispatcherServlet with name 'dispatcher'
19:15:44,421 DEBUG http-8080-1 support.DefaultFlashMapManager:199 - Saving Flash
Map=[Attributes={userId=batman, flashAttr1=flashflash}, targetRequestPath=/test-
webapp-1/protected/protected_page.jsp, targetRequestParams={attr1=[ababab]}]
19:15:44,421 DEBUG http-8080-1 servlet.DispatcherServlet:913 - Successfully comp
leted request
Following a brief stop at the filter I've shown above, I am taken to the page with URL
http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp?attr1=ababab
But neither of the attributes I expect that JSP to find are displayed. I have also debugged through the doFilter() method shown above and failed to find the flash attributes in the request's session.
I'm not sure exactly what's wrong at this point. Everything works as expected except for those flash attributes. If there is anything else I should provide to make the situation more clear, I will be happy to.
Ran into this issue a few months ago with AJAX-related redirects. If you use a read-only HTTP POST pattern, you can specify a #ResponseStatus to simulate a POST. Also be sure to have your method return a View or ModelAndView (as opposed to String) so that Spring knows to look up the Flash scope for the given #RequestMapping.
Pseudocode:
#RequestMapping(...)
#ResponseStatus(OK)
public ModelAndView login (...) {
...
}

Resources