PrimeFaces based application with PicketLink does not show style in login page - jsf-2

I developed a PrimeFaces based application that I now want to protect with PicketLink in a CDI way. I followed this example and created a login page with several PrimeFaces components including a layout). All styling and functionality is however lost. Even a simplified login.xhtml page (to match the example linked to above) does not have styling.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head/>
<h:body>
<p:panel>
<h:form method="POST" prependId="false">
<p:inputText id="j_username" />
<p:password id="j_password"/>
<p:commandButton id="login" value="Login" action="#{identity.login()}" ajax="false"/>
</h:form>
</p:panel>
<p>Tip: you can login with a username/password of jane/abcd1234.</p>
</h:body>
</html>

The reason the css and js files are not loaded is because the security 'profile' in the original example has all resources protected besides a login.xhtml file. JSF by default loads resources from the 'virtual' javax.faces.resource folder. This needs to be excluded from authentication to. The HttpSecurityConfiguration in the original example should be adapted to exlude this virtual folder in the config.
public class HttpSecurityConfiguration {
public void onInit(#Observes SecurityConfigurationEvent event) {
SecurityConfigurationBuilder builder = event.getBuilder();
builder
.http()
.forPath("/javax.faces.resource/*")
.unprotected()
.forPath("/index.jsf")
.unprotected()
.allPaths()
.authenticateWith()
.form()
.authenticationUri("/login.jsf")
.loginPage("/login.jsf")
.errorPage("/error.jsf")
.restoreOriginalRequest()
.forPath("/logout")
.logout()
.redirectTo("/index.jsf");
}
}

Related

Images ad richfaces component are not displaying in JSF2 [duplicate]

I am using PrimeFaces 3.4 in my web app and for a particular page the controls are not displayed with the normal PrimeFaces skin:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>VMS login</title>
</h:head>
<h:body>
  <h:form id="loginForm">
    <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
    <p:panel header="#{msgs['login.title']}">
      <p:panelGrid id="loginPanel" columns="2">
        <h:outputText value="#{msgs['login.username']}" />
        <p:inputText id="j_username" value="#{loginFormBean.userName}" required="true"></p:inputText>
        <p:message for="j_username" ></p:message>
        <h:outputText value="#{msgs['login.password']}" />
        <p:password id="j_password" value="#{loginFormBean.password}" required="true" feedback="false"></p:password>
        <p:message for="j_password"></p:message>
        <p:commandButton action="#{loginController.loginUsingSpringAuthenticationManager}" value="#{msgs['login.button']}" update="loginForm" ajax="true"></p:commandButton>
      </p:panelGrid>
    </p:panel>
  </h:form>
</h:body>
</html>
This outputs to:
The panel should have a header and so on.
The interesting thing is that in another page where I am using a <p:layout> with different panels in the layouts they display fine with their normal PrimeFaces look-and-feel.
What am I doing wrong? Thank you
Given that it only occurs on the login page, that can happen when the authentication mechanism also kicks on requests to JSF resources like CSS/JS/image files and redirects them to the login page as well. The webbrowser would then retrieve the HTML representation of the login page instead of the concrete resources. If you have investigated the HTTP traffic in the webbrowser's developer toolset, then you should have noticed that as well.
If you're using homegrown authentication with a servlet filter, then you need to tell the filter to not redirect them to the login page, but just continue them. It are those /javax.faces.resource/* URLs (you can get that URL path as constant by ResourceHandler#RESOURCE_IDENTIFIER).
if (request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
chain.doFilter(request, response);
return;
}
// ...
Or if you're using container managed authentication, then you should add /javax.faces.resource/* to allowed URLs which should be skipped from login checks:
<security-constraint>
<web-resource-collection>
<web-resource-name>Allowed resources</web-resource-name>
<url-pattern>/javax.faces.resource/*</url-pattern>
</web-resource-collection>
<!-- No Auth Contraint! -->
</security-constraint>
See also Exclude css & image resources in web.xml Security Constraint.
Or when you're using 3rd party authentication framework like Spring Security, then you need to tell it the following way (assuming 3.1.0 or newer)
<http security="none" pattern="/javax.faces.resource/**" />
See also Spring Security 3.0.5.
Or when you're using PicketLink, see PrimeFaces based application with PicketLink does not show style in login page.

How to keep JSF flash scope parameters on page reload?

I use flash scope to pass a setting object between #viewscoped contollers. But if I make a page reload on one of them, then the flash map is empty and the setting object is not initialized. Is it possible to keep flash scope on page reload?
My source code to store/retrieve settings:
FistPage.xhtml
...
<p:commandButton value="next"
action="#{firstPageController.transferConfig}"
process="#this" />
...
FirstPageController.java
#ManagedBean(name = "firstPageController")
#ViewScoped
public class FirstPageController {
...
public String transferConfig() {
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("searchConfig", searchConfig);
return "/secondPage.xhtml?faces-redirect=true";
}
...
}
SecondPage.xhtml
...
<h:outputLabel value="value">
<f:event type="preRenderComponent" listener="#{secondPageController.onPageLoad()}"/>
</h:outputLabel>
...
SecondPageController.java
#ManagedBean(name = "secondPageController")
#ViewScoped
public class SecondPageController {
...
public void onPageLoad()
{
flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
searchConfig = ((SearchFilterConfig) flash.get("searchConfig"));
flash.putNow("searchConfig", searchConfig);
flash.keep("searchConfig");
}
...
}
I use Mojarra 2.1.29
Thanks
I just did some tests in my playground project and realized it's actually possible to keep the state of the flash parameters even if you GET the page again, using {flash.keep}. That's how the JSF docs explain it:
The implementation must ensure the proper behaviour of the flash is preserved even in the case of a <navigation-case> that contains a <redirect />. The implementation must ensure the proper behavior of the flash is preserved even in the case of adjacent GET requests on the same session. This allows Faces applications to fully utilize the Post/Redirect/Get design pattern.
Here you've got a nice basic test case:
page1.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head />
<h:body>
<h:form>
<h:button id="nextButton" value="Next (button)" outcome="page2.xhtml" />
<c:set target="#{flash}" property="foo" value="bar" />
</h:form>
</h:body>
</html>
page2.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<head />
<body>foo = #{flash.keep.foo}
</body>
</html>
Just open the first page and click on the button which will redirect you to the second one. Then refresh the second page as many times as you want and you'll find the parameter persisting.
Tested in Mojarra 2.2.6

Redirect to XHTML file in a JSF Composite Component

I have a requirement to add a button in one of the xhtml component. When a user clicks the button, a new window should open redirecting the user to another xhtml file which is also in the same component project.
This is what I have in my component project,
|->src
|-> main
|->java
|->META-INF
|->faces-config.xml
|->resources
|->components
|->A.xhtml
|->B.xhtml
I need to add a button in A.xhtml file which redirects the user to B.xhtml opening a new window. This component is being used in other projects. I tried commandButton with target=_blank, a new window opens but doesn't redirect to B.xhtml.
I observed that if I use ui:include src="B.xhtml" tag in A.xhtml file, then the content of B appears in A. But couldn't find why it is not able to redirect in a new window. Not sure what I am missing and would like to know how this can be achieved.
#Sanjay you can easily achieve this by using primefaces commandbutton component by setting target as '_blank' and ajax as 'false'.
<h:form prependId="false" id="form" target="_blank" >
<p:commandButton value="Click me to open new url" ajax="false" action="B.xhtml"/>
</h:form>
Hope this helps .
you can't redirect to a component, you have to redirect to a PAGE that contains that component.
imagine you have
application
resources
components
A.xhtml
B.xhtml
pages
page1.xhtml
page2.xhtml
and
page1.xhtml contains component A
page2.xhtml contains component B
page1.xhtml contains
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:p="http://primefaces.org/ui"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions"
xmlns:cc="http://java.sun.com/jsf/composite/components">
<ui:composition template="/WEB-INF/templates/template.xhtml">
<ui:define name="content">
<cc:a value="someValue" foo="someBar"/>
</ui:define>
</ui:composition>
</html>
and A.xtml is
<h:form prependId="false" id="form" target="_blank" >
<p:commandButton value="open" ajax="false" action="page2.xhtml"/>
</h:form>
so, upvote for #Java, since your answer is almost correct, just change action to address a page and not a component in resources

f:viewParam doesn't pass required parameter when new xmlns.jcp.org namespace is used

I am trying to use Glassfish 4.0 with Java EE 7 XML namespaces to test the sample below.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Title</title>
</h:head>
<h:body>
<h:form>
<ul>
<ui:repeat value="#{appLoad.movieList}" var="movie">
<li>
<h:link value="#{movie.title}" outcome="movie" includeViewParams="true">
<f:param name="id" value="#{movie.id}"/>
</h:link>
</li>
</ui:repeat>
</ul>
</h:form>
</h:body>
</html>
It links to the following page movie.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<f:metadata>
<f:viewParam name="id" value="#{appLoad.movieId}"/>
<f:event listener="#{appLoad.movieDetail()}" type="preRenderView"/>
</f:metadata>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="2">
<h:panelGrid columns="1" width="400">
<h:panelGrid columns="1">
Title : <h:outputLabel value="#{appLoad.movie.title}"/>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
</h:form>
</h:body>
</html>
The #{appLoad} backing bean is
#ManagedBean
#RequestScoped
public class AppLoad {
#EJB
private MovieFacade movieFacade;
private Movie movie = new Movie();
private List<Movie> movieList;
private int movieId;
#PostConstruct
public void movieDetail(){
movieList = movieFacade.findAll();
movie = movieFacade.find(movieId);
System.out.println(movieId);
}
// Getters+setters.
}
When the index page is run, and the link is been clicked, the url outrightly changed to
result.xhtml?id=8
But no data is been displayed. Its comes as blank. I figured out that #{appLoad.movieId} is null. In other words, the <f:viewParam> does not set this request parameter.
The only work around I had was to change the XML namespaces back to the older version.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
I'm guessing I'm getting something wrong here. How is this problem caused and how am I supposed to use the new XML namespaces?
The way how the new xmlns.jcp.org XML namespaces are been handled is broken in the first Mojarra releases 2.2.0 and 2.2.1. It has been fixed in Mojarra 2.2.2 (note: ticket in the link describes different problem symptom, but under the covers, it's essentially the same cause). It's recommended to upgrade to Mojarra 2.2.2. GlassFish 4.0 has Mojarra 2.2.0 bundled. You can get the JAR from javaserverfaces.java.net. All you need to do is to replace javax.faces.jar file in GlassFish's /modules folder with the newer version.
This kind of trouble is by the way not unusual with the very first major GlassFish release (all hastle to get it ready on time). I recommend to wait with Java EE 7 until GlassFish 4.0.1 or 4.1 has been released to avoid future surprises. Note that other vendors like Apache Tomcat and JBoss AS take their time to release a stable Java EE 7 container; they do currently not have a production ready version yet.
See also:
Using new xmlns.jcp.org namespace on composites causes java.lang.NullPointerException at java.util.concurrent.ConcurrentHashMap.putIfAbsent

f:ajax method gets called on load of the jsf page

I've simple 3line jsf page and a backing bean. I'm using command button in my page. Onclick event I'm calling ajax. where ajax method adds an output text component to child. Now the problem is. Out put text component is rendered on load of the page rather than on click of the page.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:commandButton id="button1" action="return false" value="Submit">
<f:ajax execute="#{bb.method1()}" render="#form" transient="true" event="click" />
</h:commandButton>
</h:form>
</h:body>
</html>
Backing bean code
#Named("bb")
#SessionScoped
public class BackingBean implements Serializable {
public BackingBean() {
}
public void method1()
{
HtmlOutputText out=new HtmlOutputText();
out.setValue("Text1");
FacesContext context=FacesContext.getCurrentInstance();
context.getViewRoot().getChildren().add(out);
context.getViewRoot().setTransient(true);
}
}
on click of button firebug show status 200 OK.. But I can see no changes at the page
The execute attribute should refer a space separated collection of client IDs of input components which needs to be processed during ajax submit. This attribute is evaluated when the view get rendered and any method bound to it thus get invoked immediately.
You should be using the listener attribute instead.
<f:ajax listener="#{bb.method1()}" render="#form" transient="true" event="click" />
The same is true for the render attribute.
See also:
<f:ajax> tag documentation

Resources