JSF 2.0; MyFaces; Form submit only with POST - jsf

i've got a security question and i don't know, how to do this in JSF.
In PHP i can react on a form submit that is defined as POST, that i only want values via POST so there is no way to get an value via GET from the same name of the field.
Example:
fieldname in form: username
in my PHP site i can get the value via $_POST["username"] but not with $_GET["username"], because i don't implement the GET way, only POST.
So, now i want this in my JSF site too.
The problem is, that i can't only implement POST for all requests, i must react on GET also.
I only want, that my form data will come via POST to my bean and not via GET.
How can i reach this?
With a filter or something else?
For your interest: i'm not able to use JavaScript in my application.
Thanks a lot!

I'm not sure I understood your question but if you just need to check if a method on your backing bean was invoked using POST or GET you can get that information from the HttpServletRequest object like so :
#ManagedBean(name="myBean")
#ViewScoped
public class MyMBean implements Serializable{
public void handleForm(){
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
if(req.getMethod().equalsIgnoreCase("POST")){
//Handle your form data
}
}

Just check FacesContext#isPostback().
if (FacesContext.getCurrentInstance().isPostback()) {
// It's a JSF POST request.
}

Related

Cookie set in web filter is not available in request bean

I'm trying to create a localized JSF web application which allows user to select a language via dropdown. When language is selected, I simulate a redirect to the same page but with URL parameter:
window.location.replace(urlToMyApp + '?locale=DE');
Next, I read 'locale' parameter in application's web filter and write it in a cookie with the same name:
String localeValue = httpRequest.getParameter("locale");
Cookie cookie = new Cookie("locale", localeValue);
cookie.setMaxAge(-1);
cookie.setDomain(cookieDomain);
cookie.setPath(cookiePath);
httpResponse.addCookie(cookie);
Now when I try to read that cookie in request bean init method, cookie is not available. If I select another language via dropdown (EN for example), previously selected language (DE) is read in init method.
I assume that cookie written in filter is not available before next "request - response" cycle, can someone confirm that?
If that's true I'm asking for an idea to translate my application immediately after selecting another language.
Just one thing that I think I need to mention - language dropdown is not part of my application. It's part of some kind of framework for several applications to be included (like portal).
I assume that cookie written in filter is not available before next "request - response" cycle, can someone confirm that?
That's correct.
You've added the new cookie to the response, not to the request. So any attempt to read it from the same request won't work. The cookie will only be available in the request if the browser has actually sent it. But it can only do that if it has obtained the cookie data from a previous response.
If that's true I'm asking for an idea to translate my application immediately after selecting another language.
If the request scoped bean is managed by CDI #Named, then just inject it in the filter and set the locale over there.
#Inject
private Bean bean;
public void doFilter(...) {
// ...
bean.setLocale(locale);
// ...
}
Else if it's not managed by CDI, but by the since JSF 2.3 deprecated #ManagedBean, then manually instantiate it and put it in request scope so that JSF will just reuse the same bean.
public void doFilter(...) {
// ...
Bean bean = new Bean();
bean.init(); // If necessary.
bean.setLocale(locale);
request.setAttribute("bean", bean); // "bean" is managed bean name.
// ...
}
See also:
Get JSF managed bean by name in any Servlet related class
Localization in JSF, how to remember selected locale per session instead of per request/view

How do I limit a user from accesing sertain pages in JSF? [duplicate]

This question already has answers here:
How implement a login filter in JSF?
(2 answers)
Closed 2 years ago.
Like the title says, how do I limit users from accessing certain pages in JSF? I have two different kinds of pages that I want to limit access to. The first one is pages that need parameters to load, would it be possible to redirect if a user tries to redirect access that page without any parameters? The second one is pages that only certain users should have access to. In my app you have the ability to create and edit competitions, however, I only want the host of the event to be able to access the edit page for that event - which at the moment anyone can access if they know the right parameters. Is there something in JSF that lets me do this?
General page access
Have a look at #WebFilter and its doFilter method. Inside you can check if your user is logged in retrieving your session scoped bean from the HttpSession.
#WebFilter(filterName = "UserAuthenticationFilter", urlPatterns =
{
"/sites/user/account.xhtml"
} , dispatcherTypes =
{
DispatcherType.FORWARD, DispatcherType.REQUEST, DispatcherType.ERROR
})
public class UserAuthenticationFilter extends HttpFilter
{
#Override
public void doProductionFilter(final HttpServletRequest request, final HttpServletResponse response, final HttpSession session, final FilterChain chain) throws IOException, ServletException
{
final UserBean userBean = session.getAttribute("userBean");
// check if logged in and redirect to login page if not
if (userBean.isLoggedIn()
chain.doFilter(request, response);
else
response.sendRedirect(request.getContextPath() + "/login.xhtml");
}
}
Specific page access
Check your request param either in your #PostConstruct or better in your viewAction or initPreRenderView methods since in the later two you have access to your injected view parameters.
If user does not has sufficient rights to access the data redirect or/and show faces message or do something else.

JSF to Bean to JSF

So I'm having a problem trying to pass a String value.
The String value is entered through a login page as username.
The JSF then calls the Bean to verify log in information then proceeds to another JSF page.
I was wondering how to pass the username along to the new JSF page. Thank you.
If you're performing a navigation instead of a redirect, then you basically don't need to do anything. The information is also just available in the navigated page.
E.g. in login page,
<h:inputText value="#{bean.username}" />
and in the navigated page:
<p>You have entered the following username: #{bean.username}</p>
If you're however performing a redirect instead of a navigation, then you basically need to store the information in a bit broader scope. You didn't clearly elaborate the concrete functional requirement in the question, but if I guess it right, you just wanted to remember the currently logged-in user for the remaining of the HTTP session. In that case, just store it in the session scope during the login action.
public String login() {
// ...
User user = userService.find(username, password);
// ...
externalContext.getSessionMap().put("user", user);
// ...
return "nextpage?faces-redirect=true";
}
This way it's available by #{user} throughout the entire HTTP session.
<p>You're logged in as #{user.name}.</p>
You can also use <t:saveState> without using session scope. <t:saveState> is longer than the request scope but shorter than session scope.
This may help you : http://myfaces.apache.org/tomahawk-project/tomahawk12/tagdoc/t_saveState.html

JSF PhaseListener viewId always one behind

Im trying to prevent users to access special pages with a phaselistener. for that reason im trying to figure out on which page they try to access.
but my problem is, i only get the page they where before. not the actual page.
public void afterPhase(PhaseEvent event)
{
FacesContext fc = event.getFacesContext();
System.out.println("test1" + fc.getViewRoot().getViewId());
}
and same here
public void afterPhase(PhaseEvent event)
{
FacesContext fc = event.getFacesContext();
HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
String uri = request.getRequestURI();
System.out.println("uri: " + uri);
}
why is that, and how do i get the pagename the user is trying to access? Not that one that they required one step before, or better the page they are coming from.
It is one step behind because that is the way sequence of HTTP POST request behaves. When you are navigating in JSF application via command buttons each request goes as a post request.
Since you are protecting some resources make sure they are accessed via HTTP GET than you will get exact view id, this can be achieved as
User directly hits the url from address bar of browser.
After a post of jsf app redirect it to the resource instead of simple JSF navigation. POST-REDIRECT-GET pattern falls into this have a look here.
If you are showing some messages after each POST, you might need Flash map for that, which is new feature in JSF2, if you are on JSF1.x hard luck, you can implement flash if you want to.
To conclude catch the view ids on HTTP GET request.
Hope this helps...

How to pass and get URL parameters in IBM Webpshere Portal 6.1 JSF Portlets?

I have a simple HTML page which contains a form (uses GET method), whose action is a portal page containing a JSF portlet. I need to access the parameters passed in to the portal page in my portlet - how can I achieve this?
I have tried to access the parameter code on the view page using following code but the value comes up as null.
java.util.Map requestMap = javax.faces.context.FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String code = requestMap.get("code");
At some other forum it was suggested that I need to pass the the portlet id as request parameter in order to have the portlet access to passed request parameters. If that is true where/how can I lookup my portlet ID so that portlet has access to request parameters?
I would look into whether the WebSphere implementation of public render parameters supports this. If the ExternalContext request parameter map does not expose these values, you can cast the request to a PortletRequest and make use of the Map<String,String[]> getPublicParameterMap() method.
See my article Passing query parameters to JSR-286 portlets here.
I know this is a supported way to do it. I have seen other articles that claim you can simply cast the PortletRequest to something and get the parameters. This is probably not supported in that it depends on a particular implementation and reference to an internal class name. I recommend the above.

Resources