Problems with web.xml - primefaces

first of all i want to apologize for my bad English. Ok, i have a problem. I am building application that uses jdbcrealm and web.xml for security. Login is done by web form. Application is running on Apache Tomcat 7 and i am using Primefaces 4.0. In web.xml I have defined some roles and some security constraints. When I log in into application httpservlet request.login(username,password) do the job fine, and request.isUserInrole("role") also do do job, Faces.getExternalContext.redirect redirects page to correct folder on which security constraint is applied, in browser I see correct URL .....but the page is Blank!!! If I check page source I see page source of login page.....I will put some screen shots bellow. Please help me...I am trying solve problem for 2 weeks now!
/*
*/
this is web.xml
<param-name>primefaces.THEME</param-name>
<param-value>afterdark</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<security-role>
<description>Administrator A</description>
<role-name>1</role-name>
</security-role>
<security-constraint>
<display-name>Administrator A</display-name>
<web-resource-collection>
<web-resource-name>Administratorske datoteke</web-resource-name>
<description/>
<url-pattern>/a1/*</url-pattern> -->
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>Administrator A</description>
<role-name>1</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>JDBCRealm</realm-name>
<form-login-config>
<form-login-page>/prijava.xhtml</form-login-page>
<form-error-page>/pogreska.xhtml</form-error-page>
</form-login-config>
</login-config>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>prijava.xhtml</welcome-file>
</welcome-file-list>
*this is login page(prijava.xhtml)*
<div class="slika_za_prijavu">
<h:outputLink id="loginLink" value="javascript:void(0)" onclick="PF('prozor_za_unos').show()" title="prijava">
<p:graphicImage value="/slike/prijava.png" />
</h:outputLink>
</div>
<p:growl id="growl" showDetail="true" life="3000" />
<p:dialog id="prozor_za_prijavu" header="Prijava" widgetVar="prozor_za_unos" resizable="false">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="k_ime" value="Korisničko ime:" />
<p:inputText value="#{provjera_prijave.k_ime}"
id="k_ime" required="true" label="korisnicko_ime"
requiredMessage="Potrebno je upisati korisničko ime!"/>
<h:outputLabel for="zaporka" value="Zaporka:" />
<h:inputSecret value="#{provjera_prijave.zaporka}"
id="zaporka" required="true" label="zaporka"
requiredMessage="Potrebno je upisati zaporku!"/>
<f:facet name="footer">
<p:commandButton id="gumb_za_prijavu" value="Prijavi se" update="growl"
actionListener="#{provjera_prijave.prijava(actionEvent)}"
oncomplete="obrada_zahtjeva_za_prijavu(xhr, status, args)"/>
</f:facet>
</h:panelGrid>
</p:dialog>
</h:form>
this is login controller (provjera_prijave)
public void prijava(ActionEvent actionEvent) throws IOException {
FacesMessage poruka = null;
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletRequest zahtjev = (HttpServletRequest) fc.getExternalContext().getRequest();
try {
String pocetna_stranica;
zahtjev.login(k_ime, zaporka);
HttpSession sesija = zahtjev.getSession();
if (!sesija.isNew()) {
sesija.invalidate();
sesija = zahtjev.getSession();
}
if (zahtjev.isUserInRole("1")) {
sesija.setAttribute("trenutni_korisnik",k_ime);
pocetna_stranica = "/a1/pocetna_a1.xhtml";
poruka = new FacesMessage(FacesMessage.SEVERITY_INFO, "Dobro došao", k_ime);
try {
fc.getExternalContext().getFlash().setKeepMessages(true);
fc.getExternalContext().redirect(zahtjev.getContextPath()+pocetna_stranica);
}
catch (IOException ex) {
fc.addMessage(null, new FacesMessage("UPOZORENJE!", "Pogreška u izvođenju programa. Nije moguće preusmjeriti stranicu."));
}
}
else if (zahtjev.isUserInRole("2")) {
and this is url which is in my browser when user with role "1" log in. Before this goes localhost and port...ERMP is the neme of application....
"ERMP/a1/pocetna_a1.xhtml"
here is blank page with page source of login page
I hope that question is understandable.
When comment web resource in web.xml everything works
Please help!!Thank you

As you want to use the tomcat's built in (Realm) authentication and authorization, there's a couple of things you should attend to.
First, your login form needs to be something like this:
<form action="j_security_check" method="post">
<input type="text" name="j_username" placeholder="Login"/>
<input type="password" name="j_password" placeholder="Password"/>
<input type="submit" value="Sign In" />
</form>
You could use primefaces components to preserve the layout. In that case you will need to do some "javascripting" in order to define the action of the form rednered by the JSF h:form component.
...
<script>
jQuery("#form").submit(function() {
jQuery(this).attr("action", "j_security_check");
jQuery(loginVar.jqId).attr("name", "j_username");
....
});
</script>
The second detail is that you won't need to worry about the login part as described in your login controller. Once you send j_username and j_password to j_security_check, everything will run just fine.

Related

TomEE Plume 7 - JSF 2.2 navigation rules and redirects don't work - primefaces 6.1 + omnifaces 2.6.4

I have the following jsf login page:
<h:form id="frmAdmLogin" styleClass="form-horizontal">
<div class="ui-layout-center" style="margin-left: 15px;">
<p:messages id="messagesLogin" autoUpdate="true" closable="true" />
<h:panelGrid cellpadding="5">
<p:inputText id="txtUsuario" required="true" value="#{loginDataManager.usuario}" />
<p:password id="pssClave" required="true" value="#{loginDataManager.password}" />
<h:selectOneMenu id="lstSucursales" required="true" value="# {loginDataManager.idSucursal}">
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{loginController.listadoCatalogos()}" var="sucursal" itemLabel="#{sucursal.nomCatalogo}" itemValue="#{sucursal.id}" />
</h:selectOneMenu>
<p:commandButton id="loginButton" value="Ingresar" action="#{loginController.login()}" />
</h:panelGrid>
</div>
<div id="barras">
<ui:include src="/templates/main/barras.xhtml" />
</div>
</h:form>
After user logs in the application, it should redirect to the main page. But It doesn't work.
For navigate I use the following navigation rules:
<navigation-rule>
<from-view-id>/login/login.xhtml</from-view-id>
<navigation-case>
<from-action>#{loginController.login()}</from-action>
<from-outcome>login</from-outcome>
<to-view-id>/login/login.xhtml</to-view-id>
<redirect/>
</navigation-case>
<navigation-case>
<from-action>#{loginController.login()}</from-action>
<from-outcome>exito</from-outcome>
<to-view-id>/login/main.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
I have a CDI bean which has the login method:
public String login() {
validarUsuario();
try {
obtenerMenu(sessionDataManagerBase.getUserDto());
return "exito";
} catch (Exception e) {
log.error("", e);
MessagesController.addError(null, "Error al consultar las opciones de menú para el usuario");
FacesContext.getCurrentInstance().validationFailed();
return "login";
}
}
Tomee starts with no errors, and when I click the login button nothing happens: no navigation, no errors in the browser and no errors in Tomee log.
There's something I'm missing in my configuration.
Thanks.

Dialog framework does not close when it has an input field

I'm trying to close a dialog with a cancel button, I receive the event but the dialog does not close.
After a lot of digging I realize the problem is where the dialog has an input field with the ticket description, but it works when I remove it and I leave only de buttons.
Does it make any sense?
Form base code
...
<p:commandButton icon="fa fa-bug" actionListener="#{ticketBean.viewTicket}"/>
...
TicketBean code
#ManagedBean
#ViewScoped
public class TicketBean {
...
public void viewTicket() {
logger.info("--------------ViewTicket");
Map<String, Object> options = new HashMap<>();
options.put("modal", true);
options.put("width", 640);
options.put("height", 250);
options.put("resizable", false);
options.put("contentWidth", "100%");
options.put("contentHeight", "100%");
options.put("closable", false);
RequestContext.getCurrentInstance().openDialog("maintenance/ticket", options, null);
}
public void cancel() {
RequestContext.getCurrentInstance().closeDialog(null);
}
...
ticket.xhtml dialog code DOES NOT WORK
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>#{msgs.ticket_create}</title>
</h:head>
<h:body>
<h:form id="frmTicket">
<p:inputTextarea rows="5" cols="70" value="#{ticketBean.ticket.descripcio}" >
</p:inputTextarea>
<br/>
<h:inputHidden value="#{ticketBean.ticket.path}" />
<p:commandButton value="#{msgs.save}" style="width:auto"
styleClass="GreenButton"
actionListener="#{ticketBean.save}"/>
<p:commandButton value="#{msgs.cancel}" style="width:auto"
styleClass="RedButton"
actionListener="#{ticketBean.cancel}"/>
</h:form>
</h:body>
</html>
ticket.xhtml dialog code DOES WORK
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>#{msgs.ticket_create}</title>
</h:head>
<h:body>
<h:form id="frmTicket">
<p:commandButton value="#{msgs.save}" style="width:auto"
styleClass="GreenButton"
actionListener="#{ticketBean.save}"/>
<p:commandButton value="#{msgs.cancel}" style="width:auto"
styleClass="RedButton"
actionListener="#{ticketBean.cancel}"/>
</h:form>
</h:body>
</html>
faces-config.xml
...
<application>
<action-listener>
org.primefaces.application.DialogActionListener
</action-listener>
<navigation-handler>
org.primefaces.application.DialogNavigationHandler
</navigation-handler>
<view-handler>
org.primefaces.application.DialogViewHandler
</view-handler>
</application>
...
web.xml
...
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
...
The solution is to change the code
<p:inputTextarea rows="5" cols="70" value="#{ticketBean.ticket.descripcio}" >
</p:inputTextarea>
for this one
<h:inputTextarea rows="5" cols="70" value="#{ticketBean.ticket.descripcio}" >
</h:inputTextarea>
The problems seems to be with the coponent p:inputTextarea
*Possible primefaces 6 bug

always showing access denied page using spring security in struts2

I am developing a simple struts2 login page using spring security.The problem is that whenever I login, it always show my custom access denied page no matter the user is valid or not. I don't understand the error, as no error is showing except a warning:
org.apache.struts2.components.ServletUrlRenderer.warn No configuration found for the specified action: 'j_spring_security_check' in namespace: '/'. Form action defaulting to 'action' attribute's literal value.
my web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>/jsp/index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
my applicationContext-security.xml
<http auto-config="true">
<intercept-url pattern="/direct.action" access="permitAll()" />
<intercept-url pattern="/admin.action" access="hasRole('ROLE_Admin')" />
<access-denied-handler error-page="/jsp/deniedAccess.jsp" />
<form-login login-page="/jsp/login.jsp" default-target-url="/admin.action"
authentication-failure-url="/validateUser.action?error"
username-parameter="username" password-parameter="password" />
<logout logout-success-url="/logout.action?logout" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user" password="user" authorities="ROLE_User" />
<user name="admin" password="admin" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
struts.xml
<struts>
<package name="default" extends="struts-default" namespace="/">
<action name="direct" class="action.LogAction" method="reDirect">
<result name="success">/jsp/login.jsp</result>
</action>
<action name="admin" class="action.LogAction" method="directAdmin">
<result name="success">/admin/adminHome.jsp</result>
</action>
<action name="validateUser" class="action.LogAction" method="errorDirect">
<result name="success">/jsp/login.jsp</result>
</action>
<action name="logout" class="action.LogAction" method="directLogout">
<result name="success">/jsp/login.jsp</result>
</action>
</package>
index.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Redirecting...</title>
</head>
<body>
Redirecting...
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=direct.action">
</body>
I don't know what is the error.Any help will be appreciated
login.jsp
<s:form action="j_spring_security_check" namespace="/" method="post">
<s:textfield name="username" label="Username"/>
<s:password name="password" label="Password"/>
<s:submit align="center" value="Login"/>
</s:form>
Your login.jsp form tag points at j_spring_security_check, which isn't an action name in your struts.xml. Change that to whatever action name which will handle the login post.
If you have written a method in action.LogAction (or implemented execute()) to actually handle your login, you need to provide both a success and a failure result in the struts.xml The success result should take the user to wherever they should be after successful login, the failure result takes them back to the login jsp. See the struts docs here for more info.

My Basic jsf tags are not rendering in to html tags

Im a Totally new in Java and JSF. I'm using eclipse Indigo and Tomcat 6.0.3 and JSF 2.0.
When i run the Page in Browser, I just get an empty page, but i could the elements in firebug that it is still in JSF tags itself. It is not rendering in html..
This is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>ContactFormJSF</display-name>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<welcome-file-list>
<welcome-file>pages/index.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>*.xhtml</param-value>
</context-param>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
This is my Basic JSF content
<?xml version="1.0" encoding="UTF-8" ?>
<!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">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Add New User Form</title>
</h:head>
<h:body>
<f:view>
<h:form>
<h:panelGrid border="1" columns="3">
<h:outputText value="Name"></h:outputText>
<h:inputText value="#{userBean.name}" required="true"></h:inputText>
<h:outputText value="D.O.B"></h:outputText>
<h:inputText id="DOB" value="#{userBean.dob}" required="true"> </h:inputText>
<h:outputText value="Age"></h:outputText>
<h:inputText id="age" value="#{userBean.age}" required="true"> </h:inputText>
<h:commandButton action="#{userBean.addUser}" value="Submit"></h:commandButton>
<input type="reset"/>
<h:commandButton action="#{userBean.reset}" value="Reset"> </h:commandButton>
</h:panelGrid>
</h:form>
</f:view>
</h:body>
</html>
Iam Struggling for this for a week, I have tried out many things noted down in stackoverflow..
The URL iam using is localhost:8080/ContactFormJSF/
I could see the HTML tags which is added above in the Browser but not the jsf tags..
Actually, the FacesServlet mapping in your web.xml doesn't cover the .xhtml files, so you should add the proper mapping to the configuration file:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
In other side, you should retreive this to let the JSF controller recognize the .xhtml files in your project:
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>*.xhtml</param-value>
</context-param>

jsf2 facesmessage for spring-security badcredentials

I use a facelets login form for Spring Security:
<h:messages globalOnly="true" layout="table" />
<h:form id="formLogin" prependId="false">
<h:outputLabel for="j_username" value="Usuario:" />
<h:inputText id="j_username" value="#{autenticacionController.administrador.login}" />
<h:outputLabel for="j_password" value="Contraseña:" />
<h:inputSecret id="j_password" value="#{autenticacionController.administrador.password}" />
<h:commandButton value="Entrar" action="#{autenticacionController.loginAction}" />
<h:commandButton value="Cancelar" immediate="true" action="#{autenticacionController.cancelarAction}" />
</h:form>`
The loginAction method forwards the request with this:
FacesContext.getCurrentInstance().getExternalContext().dispatch("/j_spring_security_check")
It works fine, but how can I show a facesmessage in my h:messages tag if the BadCredentials exception is thrown by Spring Security?
I know it can be done with a phase listener, but I don't like that way (dealing with exceptions in listeners).
I'm trying another way, configuring Spring Security like this:
authentication-failure-url="/faces/paginas/autenticacion/login.xhtml?error=1
And then in the login page, catch the GET param "error". But how can I show the facesmessage in this way?
Another way I tried was to override the messages properties file of Spring Security (overriding the message for the key "badcredentials"), but it didn't work neither (I didn't know how to show the message).
Anyone know how to do it?
Thank you very much in advance.
And then in the login page, catch the GET param "error". But how can I show the facesmessage in this way?
This way:
<f:metadata>
<f:viewParam name="error" validator="#{auth.checkErrors}" />
</f:metadata>
<h:messages />
with
public void checkErrors(FacesContext context, UIComponent component, Object value) {
if ("1".equals(value)) {
throw new ValidatorException(new FacesMessage("Invalid credentials"));
}
}
or maybe so:
<f:metadata>
<f:viewParam name="error" value="#{auth.error}" />
<f:event type="preRenderView" listener="#{auth.checkErrors}" />
</f:metadata>
<h:messages />
with
private int error;
public void checkErrors() {
if (error == 1) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Invalid credentials"));
}
}
Either way, this feels pretty hacky :)