How can you redirect a user by URL (within backing bean) to some other page within portlet? We are using GateIn 3.1 on JBoss 5.1.0
Usually, FacesContext.getCurrentInstance().getExternalContext().redirect("url") is enough, but here it doesn't work, it doesn't redirect user.
context.getApplication().getNavigationHandler().handleNavigation(context, null, page) doesn't work either.
We want to avoid making navigation rules for every possible page we can redirect to.
EDIT:
It appears a4j:commandButton was causing some problems, after we replaced it with h:commandButton we are being redirected but not only within portlet but within portal.
To have sendRedirect available, you have to cast object response to HttpServletResponse :
HttpServletResponse objHttpServletResponse = (HttpServletResponse)
FacesContext.getCurrentInstance()
.getExternalContext()
.getResponse();
objHttpServletResponse.sendRedirect(url);
This is doing a 302 redirect, managed by browser.
The only other alternative (to having many navigation cases in faces-config.xml) I've found that works is using FacesContext.getCurrentInstance().getViewRoot().setViewId(page) to redirect, where page is String page = FacesContext.getCurrentInstance().getViewRoot().getViewId().
Related
I have developed one application and facing issue with security stuff.
My application is running in doPost method which doesn't explicit the URL in browser. If I'm trying to change the doPost to doGet (using webdeveloper tools-->Forms), my application's URL will be displaying explicitly. So I need to throw an error/stop app response, If user tries to change the forms from doPost to doGet ?
I suppose the question here is: Why do you regard it as a security issue, that the URL might be displayed in the browser?
In case you don't want the user to have access to the URL or other request data, you probably have fundamental design problem, as the user can track the post request using the developer tools.
In case you don't want somebody else than the user to see the URL and thus think it should not be displayed in the browser, I would not worry, as the user has to actively and consciously "mess" with your application to achieve this behavior.
In general it is probably a good idea to throw errors and prevent the request from being processed if your front end does not behave as expected.
I am trying to solve URL login issue in GWT. We are using spring security. The problem is that everything is working in development mode but in tomcat where builded as WAR it fails.
application-context-security.xml seetings:
<form-login authentication-success-handler-ref="mySuccessHandler" authentication-failure-handler-ref="myFailureHandler" login-processing-url="/login" />
I have my own login.html file there si HTML form element <form action="/login">
I have two Spring handlers which redirects to Login.html or MyApplication.html (content,services) depends on if user autheticates or not.
If I pack my application into vsp.war (localhost:8080/vsp/) and run it, it goes to Login.html, which is correct. But always if I authenticate or not it goes to localhost:8080/login with 404 status.
My final WAR structure is:
login
login.nocache.js
vsp
vsp.nocache.js
Login.html
MyApplication.html
I have two modules for login and for rest of application (services).
Example of failure authentication handler method:
#Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
// always send HTTP 403
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
final StringBuilder URL = new StringBuilder("Login.html?");
if(!GWT.isProdMode()) {
URL.append("gwt.codesvr=127.0.0.1:9997&");
}
URL.append("error=true");
response.sendRedirect(URL.toString());
}
Can anybody help me where I am doing mistake? Problem is that I dont understand the URLs if there must be /Login.html or Login.html ot /login or something different.
Any help will be appreciated.
Regards Lukas
Problem solved. I have used /login fo Spring security login but also Login.gwt.xml, Login.java for GWT parts. And there was problem with correct URLs. When I change Spring security login to something different (/differentLogin) everythinkg works fine in hosted and web mode.
I have a GWT app that is loaded within an iFrame. The app uses GWTP for client server communication. In the ActionHandler implementation a HttpSession Provider is injected.
#Inject
private final Provider<HttpSession> sessionProvider;
If cookies are disabled in the browser, a new HttpSession is provided each time the provider calls .get()
requestProvider.get();
So, there is no chance to store any information in the http session.
How can this problem be solved?
Is there a way to add the jsessionid to each action request and if so, how do I get the jsessionid?
Are you looking for the approach that is described here. The technique relies on url rewrite for sessionid.
You can also reference section "Using URL Rewriting Instead of Cookies" from oracle documentation here.
What is difference between a navigation in JSF
FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, url);
and a redirect
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.sendRedirect(url);
and how to decide when to use what?
The issue with navigation is that page URL does not change unless faces-redirect=true is added to the query string of the navigation URL. However, in my case appending faces-redirect=true throws error if I want to redirect to a non-JSF page like a plain HTML page.
And another option is as BalusC suggested at JSF 2.0 redirect error
First of all, the term "redirect" is in web development world the action of sending the client an empty HTTP response with just a Location header with therein the new URL on which the client has to send a brand new GET request. So basically:
Client sends a HTTP request to somepage.xhtml.
Server sends a HTTP response back with Location: newpage.xhtml header
Client sends a HTTP request to newpage.xhtml (this get reflected in browser address bar!)
Server sends a HTTP response back with content of newpage.xhtml.
You can track it with the webbrowser's builtin/addon developer toolset. Press F12 in Chrome/IE9/Firebug and check the "Network" section to see it.
The JSF navigationhandler doesn't send a redirect. Instead, it uses the content of the target page as HTTP response.
Client sends a HTTP request to somepage.xhtml.
Server sends a HTTP response back with content of newpage.xhtml.
However as the original HTTP request was to somepage.xhtml, the URL in browser address bar remains unchanged. If you are familiar with the basic Servlet API, then you should understand that this has the same effect as RequestDispatcher#forward().
As to whether pulling the HttpServletResponse from under the JSF hoods and calling sendRedirect() on it is the proper usage; no, that isn't the proper usage. Your server logs will get cluttered with IllegalStateExceptions because this way you aren't telling JSF that you've already taken over the control of the response handling and thus JSF shouldn't do its default response handling job. You should in fact be executing FacesContext#responseComplete() afterwards.
Also, everytime whenever you need to import something from javax.servlet.* package in a JSF artifact like a managed bean, you should absolutely stop writing code and think twice if you're really doing things the right way and ask yourself if there isn't already a "standard JSF way" for whatever you're trying to achieve and/or if the task really belongs in a JSF managed bean (there are namely some cases wherein a simple servlet filter would have been a better place).
The proper way of performing a redirect in JSF is using faces-redirect=true query string in the action outcome:
public String submit() {
// ...
return "/newpage.xhtml?faces-redirect=true";
}
Or using ExternalContext#redirect() when you're not inside an action method such as an ajax or prerender listener method:
public void listener() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/newpage.xhtml");
}
(yes, you do not need to put a try-catch around it on IOException, just let the exception go through throws, the servletcontainer will handle it)
Or using NavigationHandler#handleNavigation() in specific cases if you're using XML navigation cases and/or a custom navigation handler with some builtin listener:
public void listener() {
// ...
FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler nh = fc.getApplication().getNavigationHandler();
nh.handleNavigation(fc, null, "/newpage.xhtml?faces-redirect=true");
}
As to why the navigation handler fails for "plain HTML" files, that is simply because the navigation handler can process JSF views only, not other files. You should be using ExternalContext#redirect() then.
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
When should I use h:outputLink instead of h:commandLink?
Is there a way to go to a url without redirecting to it? Basically I want to call a url from within my application in the background so it can logout a reliant party.
Appreciate the help.
What you are trying to do does not compete us to answer as it's directly related to your own Authentication implementation.
A normal ASP.NET Authentication based in Forms Authentication you will need always to lunch the url from a browser as it is there that relies the Authentication given.
You can give yourself a try by opening your website and log in into it, after that, open other browser brand (not browser window) into your application url... you will see that you also need to login again as the Authentication is hook up into the first browser.
It's Up to you as Application Architect to make this by implementing another way of authentication, normally in this kind'a cases, this happend when consuming web services where you need a authentication code first (given by calling a Login method) and that code is always needed to be appended to the body or header of any call to the system.
This way you can easily remove the authentication code and all procedure calls will fail.
As said, this is not up to us, it's up to you to create the correct Authentication Layer.
from your comment
it's as simple as using WebClient object
WebClient client = new WebClient ();
string reply = client.DownloadString (address);
If you wish to transfer to a new url request you can still use
Server.TransferRequest()
The problem with this is that by not using a redirect the browsers address bar will not reflect the fact that you have moved their request to another URL.
To have the client visit a given URL in the background you should either make an AJAX call to it or possibly have an image with an src of your logout url (though you'd have to make sure that you return a FileResult of your image too). This is how most analytics packages call to their relevant urls in the background.
The problem here though is that neither is 100% reliable, turn off javascript or images on your browser and these results fail.
From what you've said I think what you're after is for a user to continue to any of a variety of pages rather than a specific logout page. If this is indeed the case your best solution is in fact a double redirect.
Have your application redirect to your logout url but before hand put the url of the page you want them to go to into tempdata. Then in the actionresult for the logout page you can do your logging out as required and return a redirect to the url from tempdata.