Struts 2 + Waffle: User principal is always null - security

I am working on a Web application based on Java, JSP, Struts 2 and Waffle for security. I run it in Tomcat 6. My problem is that I cannot get a principal object in my ActionSupport class. To be more specific,
principalProxy.getUserPrincipal()
always returns null. When I put this in a .jsp file, however:
request.getUserPrincipal()
this does not return null. So the information must be available in the original HttpServletRequest object. Of course, I have tried calling getUserPrincipal() on the HttpServletRequest object in the ActionSupport class, but this also returns null.
My ActionSupport class is defined as
public class SomeAction extends ActionSupport
implements ServletRequestAware, ServletResponseAware, PrincipalAware {
...
Furthermore, my struts.xml defines an action with the servlet-config interceptor set, so the setPrincipalProxy() method does actually get called (verified by print statements). This is my struts.xml (shortened):
<package name="default" namespace="/" extends="struts-default">
<action name="some" class="com.my.package.SomeAction">
<interceptor-ref name="servlet-config" />
<interceptor-ref name="params">
<param name="excludeParams ">(.*)</param>
</interceptor-ref>
<interceptor-ref name="i18n"/>
<result name="success">/someresult.jsp</result>
</action>
</package>
The web.xml defines a security filter and a filter mapping that should match any URL. Here are the relevant parts:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class>
<init-param>
<param-name>principalFormat</param-name>
<param-value>fqn</param-value>
</init-param>
<init-param>
<param-name>roleFormat</param-name>
<param-value>both</param-value>
</init-param>
<init-param>
<param-name>allowGuestLogin</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>securityFilterProviders</param-name>
<param-value>
waffle.servlet.spi.BasicSecurityFilterProvider
waffle.servlet.spi.NegotiateSecurityFilterProvider
</param-value>
</init-param>
<init-param>
<param-name>waffle.servlet.spi.NegotiateSecurityFilterProvider/protocols</param-name>
<param-value>
Negotiate
NTLM
</param-value>
</init-param>
<init-param>
<param-name>waffle.servlet.spi.BasicSecurityFilterProvider/realm</param-name>
<param-value>WaffleFilterDemo</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
When requesting SomeAction, I am prompted with a HTTP Basic Authentication dialog as desired. This shows that the SecurityFilter does in fact get applied, doesn't it? The setPrincipalProxy() method gets called as well. I can get a Principal object in the JSP page. So why is the Principal object always null when I try to access it in SomeAction?
One more thing, I am employing URL rewriting, in case that could have anything to do with it.
EDIT:
In response to batbaatar's request, the setting of the request in Java. Could not be much simpler.
#Override
public void setServletRequest(HttpServletRequest request) {
httpRequest = request;
}
The instance variable httpRequest is of type HttpServletRequest.

I still could not get a user principal object from the HTTPServletRequest. However, I am able to get a principal object from the Session:
private String getLoggedInUser() {
if (httpSession.containsKey(WAFFLE_PRINCIPAL_KEY)) {
WindowsPrincipal principal =
(WindowsPrincipal) httpSession.get(WAFFLE_PRINCIPAL_KEY);
return principal == null ? "" : principal.getName();
} else {
return "";
}
}
The session key is defined as:
private static final String WAFFLE_PRINCIPAL_KEY =
"waffle.servlet.NegotiateSecurityFilter.PRINCIPAL";
Still curious for an answer to the original question, though.

Related

Groovy: trouble printing out attributes from xml

I am trying to parse a xml file and print out attributes but it is not working.
Here is the Groovy code:
def Server1 = new XmlParser().parse('c:\\temp\\webSimplified.xml')
Server1.each {
println "Stuff in session-config: ${it}"
it.attributes().each {
println 'PLEASE PRINT OUT ATTRIBUTES: '
println it.toString()
}
}
Here is the webSimplified.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
And here is the results from running my Groovy script: Nothing prints out from the 'it.attributes().each {' segment. How can I get that to work?
Stuff in session-config: {http://xmlns.jcp.org/xml/ns/javaee}servlet[attributes={}; value=[{http://xmlns.jcp.org/xml/ns/javaee}servlet-name[attributes={}; value=[jsp]], {http://xmlns.jcp.org/xml/ns/javaee}servlet-class[attributes={}; value=[org.apache.jasper.servlet.JspServlet]], {http://xmlns.jcp.org/xml/ns/javaee}init-param[attributes={}; value=[{http://xmlns.jcp.org/xml/ns/javaee}param-name[attributes={}; value=[fork]], {http://xmlns.jcp.org/xml/ns/javaee}param-value[attributes={}; value=[false]]]], {http://xmlns.jcp.org/xml/ns/javaee}init-param[attributes={}; value=[{http://xmlns.jcp.org/xml/ns/javaee}param-name[attributes={}; value=[xpoweredBy]], {http://xmlns.jcp.org/xml/ns/javaee}param-value[attributes={}; value=[false]]]], {http://xmlns.jcp.org/xml/ns/javaee}load-on-startup[attributes={}; value=[3]]]]
Stuff in session-config: {http://xmlns.jcp.org/xml/ns/javaee}session-config[attributes={}; value=[{http://xmlns.jcp.org/xml/ns/javaee}session-timeout[attributes={}; value=[30]]]]
Process finished with exit code 0
Of course nothing is printed. I taught you in the other answer how to print out attributes, butt you have no attributes, but child tags.
Try this:
def Server1 = new XmlParser().parse(/c:\temp\webSimplified.xml/)
Server1.each {
println "Stuff in ${it.name().localPart}: $it"
println()
it.children().each {
println 'PLEASE PRINT OUT child element: '
println it
println()
}
3.times { println() }
}
This works:
def Server1 = new XmlParser().parseText('''
<web-app
version="3.1">
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
''')
Output:
servlet-name : jsp
servlet-class : org.apache.jasper.servlet.JspServlet
init-param :
init-param :
load-on-startup : 3
session-timeout : 30
Assuming you want to print the sesssion config values (a qualified guess based on your question), the following would work:
def str = '''
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
'''
def xml = new XmlParser().parseText(str)
xml.'session-config'.'*'.each { node ->
println "${node.name().localPart} -> ${node.text()}"
}
note that node is an instance of groovy.util.Node and node.name() returns an instance of QName which is a namespace aware object. To get the 'local name' we call 'localPart' on the QName.
The gpath expression xml.'session-config'.'*'.each means:
from the root node (i.e. the xml variable here), select all child nodes with the name 'session-config' and then iterate over all child nodes under that node.
The above prints:
session-timeout -> 30

Exception handling with JSF in web.xml

The problem is that I don't completely understand what exceptions are handled and what aren't.
I created new com.me.exceptions.InvalidPasswordException and populated it in the web.xml along with other exceptions:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</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>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>/view/login.xhtml</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/view/login.xhtml?faces-redirect=true</location>
<error-page>
<exception-type>com.me.exceptions.InvalidPasswordException</exception-type>
<location>/view/loginWrongPass.xhtml?faces-redirect=true</location>
</error-page>
<error-page>
<exception-type>java.io.IOException</exception-type>
<location>/view/404.xhtml?faces-redirect=true</location>
</error-page>
<filter>
<filter-name>AuthFulter</filter-name>
<filter-class>com.me.beans.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFulter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
I throw it from the my LoginBean:
#ManagedBean(name = "loginBean")
#SessionScoped
public class LoginBean implements Serializable {
private static final long serialVersionUID = 1L;
private String userName;
private String password;
!!!getters and setters are omitted
public String login() throws InvalidPasswordException, IOException {
int result = UserDao.login(userName, password);
if (result == 0) {
System.out.println("home");
return "home";
}
else if (result == 1) {
throw new InvalidPasswordException();
}
}
}
Why my InvalidPasswordException is not handled? Also if I throw IOException from the same place, it also doesn't work, though IOException is handled if it is thrown in the case of wrong URI in the request.
Though I can see stack traces of both in the logs.
Also I tried to throw exceptions from filters, it also works fine.
in general throw InvalidPasswordException or InvalidUsernameException is not good practice. User pass credentials if you find user from db you will do login, if not return null and redirect to another page or the same page show message "user not found" . You are not compare password for throw exception!.
The first your method must be change to
public String login(){
UserObject resultObject = UserDao.login(userName, password);
if (resultObject == null) {
System.out.println("user not found ");
return "home";
}
if (resultObject != null) {
System.out.println("user in database ");
System.out.println("create user profile context " +resultObject.getEmail() + " saving user object to session);
return "userProfilePage";
}
return null;
}
After changing logic you can throw exception if you need instead of returning/redirecting , but throw / catch is not best practice "
"Do NOT throw exceptions if you can avoid it, it makes your code MUCH slower ".

How to upload files without turning it to temporary file? (NetBeans JSF Primefaces)

Good day to all!
I've been making a simple web Application using Netbeans, JSF and Primefaces that can upload .csv, .jpeg/.jpg and .pdf files. I made 2 folders which was stored in drive C: (uploaded folder and tmp folder).
I assigned the "uploaded" folder to where the uploaded files are stored and the "tmp" for the .tmp of the uploaded files. I've been through many question threads and video tutorial which I followed correctly.
I also downloaded the commons fileupload and commons io and added it to the library. It is working fine, it displays that it is uploading and even saw the .tmp file on the folder i assigned it to.
But I cannot see the uploaded files on my "uploaded" folder.
So, my question is,
How can I upload these files into my "uploaded" folder.
Here are my codes:
index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form enctype="multipart/form-data" >
<p:fileUpload fileUploadListener="#{FileUploadControl.fileUploadControl}"
mode="advanced"
update="messages"
auto="true"
sizeLimit="10000000"
allowTypes="/(\.|\/)(gif|jpe?g|csv|pdf)$/"
/>
<!-- -->
<p:growl id="messages" showDetail="true"/>
</h:form>
</h:body>
</html>
FileUploadControl.java
package controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.UploadedFile;
#ManagedBean
#SessionScoped
public class FileUploadControl implements Serializable {
private String destination = "C:\\uploaded\\";
private UploadedFile file;
public UploadedFile getFile() {
return file;
}
public void setFile(UploadedFile file) {
this.file = file;
}
public FileUploadControl() {
}
public void TransferFile(String fileName, InputStream in) {
try {
OutputStream out = new FileOutputStream(new File(destination + fileName));
int reader = 0;
byte[] bytes = new byte[(int) getFile().getSize()];
while ((reader = in.read(bytes)) != -1) {
out.write(bytes, 0, reader);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public void upload() {
String extValidate;
if (getFile() != null) {
String ext = getFile().getFileName();
if (ext != null) {
extValidate = ext.substring(ext.indexOf(".")+1);
} else {
extValidate = "null";
if (extValidate.equals("pdf")) {
try {
TransferFile(getFile().getFileName(), getFile().getInputstream());
} catch (IOException ex) {
Logger.getLogger(FileUploadControl.class.getName()).log(Level.SEVERE, null, ex);
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Wrong", "Error Uploading file..."));
}
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Succesful", getFile().getFileName() + "is uploaded."));
} else {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Wrong_ext", "only extension .pdf"));
}
}
} else {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Wrong", "Select File!"));
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<!--File upload commons -->
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
<init-param>
<param-name>thresholdSize</param-name>
<param-value>51200</param-value>
</init-param>
<init-param>
<param-name>uploadDirectory</param-name>
<param-value>C:\tmp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<!--File upload commons -->
<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>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
Thank you for your response and help. looking forward to it!
The main reason it's failing as at now is that you haven't bound the value attribute to your backing bean variable, so getFile() will always return null and upload will do nothing.
You're still probably not going to get any results because it appears that you're trying to combine two different modes of operation of the <p:fileUpload/> component.
Simple mode
You don't define a fileUploadListener
You define a value attribute on the component and bind to the UploadedFile type attribute in your backing bean (which you have)
Advanced mode
You don't define a value attribute
You define a fileUploadListener which is bound to a method in your backing bean (which you also have)

Wro4j Custom XML Model Location

I've put wro.xml in src/main/resources as there are some other resources and it's easier to access them in unit tests.
I need to extend some wro classes now to be able to read the model from another place, but can't get it working.
Necessary code
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>WebResourceOptimizer</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>wroFilter</param-value>
</init-param>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WebResourceOptimizer</filter-name>
<url-pattern>/resources/*</url-pattern>
</filter-mapping>
applicationContext.xml:
<bean id="wroFilter" class="ro.isdc.wro.http.ConfigurableWroFilter">
<property name="properties" ref="wroProperties" />
</bean>
<bean id="wroProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:wro.properties" />
</bean>
wro.properties:
managerFactoryClassName=com.example.web.wro.manager.factory.MyWroManagerFactory;
preProcessors=cssUrlRewriting,cssImport,semicolonAppender,lessCss
postProcessors=cssMin,jsMin
debug=true
MyWroManagerFactory:
public class MyWroManagerFactory extends CopyrightKeeperConfigurableWroManagerFactory {
private static final Logger LOG = LoggerFactory.getLogger(MyWroManagerFactory.class);
#Override
protected WroModelFactory newModelFactory() {
LOG.debug("Load wro.xml directly from classpath");
return new XmlModelFactory() {
#Override
protected InputStream getModelResourceAsStream() throws IOException {
final String resourceLocation = getDefaultModelFilename();
final InputStream stream = getClass().getResourceAsStream(resourceLocation);
if (stream == null) {
throw new IOException("Invalid resource requested: " + resourceLocation);
}
return stream;
}
};
}
}
CopyrightKeeperConfigurableWroManagerFactory:
public class CopyrightKeeperConfigurableWroManagerFactory extends ConfigurableWroManagerFactory {
private static final Logger LOG = LoggerFactory.getLogger(CopyrightKeeperConfigurableWroManagerFactory.class);
private static final String[] PROCESSORS = {
CssImportPreProcessor.ALIAS,
JawrCssMinifierProcessor.ALIAS,
CssMinProcessor.ALIAS,
JSMinProcessor.ALIAS
};
#Override
protected void contributePreProcessors(final Map<String, ResourcePreProcessor> map) {
for (String processor : PROCESSORS) {
if (map.containsKey(processor)) {
LOG.debug("Apply CopyrightKeeperProcessorDecorator on " + processor);
map.put(processor, CopyrightKeeperProcessorDecorator.decorate(map.get(processor)));
}
}
}
}
Why it can't find classes/wro.xml / How to use a custom location for wro.xml?
EDIT
Here's the full log output: http://pastebin.com/NeNy1NH4
The problem is that you are loading the model relative to the MyWroManagerFactory class:
final InputStream stream = getClass().getResourceAsStream(resourceLocation);
That means that it will look for the model in the folder where the class is located. Since your wro.xml is located in classes folder (which is a root for classpath), you should use the following:
ClassLoader.getSystemResourceAsStream(resourceLocation);
Alternatively you could use ClasspathUriLocator:
new ClasspathUriLocator().locate("classpath:" + resourceLocation)
EDITED:
Apparently this example discovered a problem which is described in the following issue:
Until the fix is ready, the following options are available:
Option 1
Option 2

Servlet filter which is mapped on /home is not invoked when I open /home.xhtml

I am new to Java Enterprise Edition. I started learning from some YouTube videos, and recently started reading http://docs.oracle.com/javaee/6/tutorial/doc/ I finished chapter 15.
I tried to make my own filter.
I didn't use Java Servlet class. Because I want to use JSF pages, and as far as I know it is only possible to use Managed Beans with JSF pages, Whereas Servlet classes work with JSP. It is OK.
As far as I know the usefulness of login filter:
https://stackoverflow.com/tags/servlet-filters/info
[...] This is particularly useful when you have multiple pages for which
you'd like to check the logged-in user. Instead of copypasting the
same logic over all pages, you can use a Filter to have it in a single
place.
It is useful (as I know) in the case when a user type the URL directly into the browser for a page which require logged in user, so the filter will redirect him to the login page or continue if he is logged in.
I searched for any simple example to learn from but didn't find. I will put my simple example:
I have two JSF pages
one is named home.xhtml (which require logged in user)
the other one is named login.xhtml (filter must redirect to it if non-logged users seek home)
login.xhtml:
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="name:"/> <h:inputText value="#{user.name}"/>
<h:outputLabel value="password:"/> <h:inputSecret value="#{user.password}"/>
</h:panelGrid>
<h:commandButton id="btn" value="login" action="#{user.login()}"/>
</h:form>
home.xhtml:
<h:body>
Hello #{user.name}. You are welcome
</h:body>
User:
#ManagedBean
#SessionScoped
public class User implements Serializable
{
String name;
String password;
Authentication authentication;
public User()
{
authentication = new Authentication();
}
//Getters and Setters for name and password.
public String login()
{
if (this.getName().equals("user") &&(this.getPassword().equals("1234")))
{
authentication.setLoggedIn(true);
FacesContext context = FacesContext.getCurrentInstance();
context.getExternalContext().getSessionMap().put("auth", authentication);
return "home";
}
else
{
authentication.setLoggedIn(false);
FacesContext context = FacesContext.getCurrentInstance();
context.getExternalContext().getSessionMap().put("auth", authentication);
return "login";
}
}
}
Authentication:
#ManagedBean
#SessionScoped
public class Authentication implements Serializable
{
private boolean authenticated;
public Authentication()
{
authenticated = false;
}
public boolean isLoggedIn()
{
return authenticated;
}
public void setLoggedIn(boolean authenticated)
{
this.authenticated = authenticated;
}
}
LoginFilter:
#WebFilter(value = "/home")
public class LoginFilter implements Filter
{
#Override
public void init(FilterConfig filterConfig) throws ServletException
{
//throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException
{
HttpServletRequest req = (HttpServletRequest) request;
Authentication auth = (Authentication) req.getSession().getAttribute("auth");
if (auth != null && auth.isLoggedIn())
{
System.out.println("Filter is working");
chain.doFilter(request, response);
} else
{
System.out.println("Filter is working");
HttpServletResponse res = (HttpServletResponse) response;
res.sendRedirect(req.getContextPath() + "/login.xhtml");
}
}
#Override
public void destroy()
{
//throw new UnsupportedOperationException("Not supported yet.");
}
}
faces-config:
<navigation-rule>
<from-view-id>/login.xhtml</from-view-id>
<navigation-case>
<from-outcome>home</from-outcome>
<to-view-id>/home.xhtml</to-view-id>
<redirect/>
</navigation-case>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/login.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
web.xml:
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</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>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/login.xhtml</welcome-file>
</welcome-file-list>
Now when I type the URL of home.xhtml page (after clearing history & cookies) into the browser it is assumed to redirect me to login page. But instead it goes to home with empty value for name:
Hello #{user.name}. You are welcome is rendered as Hello . You are welcome
Even System.out.println("Filter is working"); not print anything.
Are you sure the filter is called? If there is nothing printed to System.out I guess not. The problem might be the servlet mapping.
You specified this:
#WebFilter(value = "/home")
public class LoginFilter implements Filter {...}
I think this only matches the url /home. Try to use /* or /home* (which is very limiting, I would not recommend it) instead.
Another thing: If you get Hello #{user.name}. You are welcome as output, then the FacesServlet is probably not called. This might have two reasons:
You use the wrong mapping. Try to call the page with /faces/home.xhtml or /home.jsf instead. The url depends on the type of mapping you have in the web.xml.
The FacesServlet is not configured correctly/at all in the web.xml.

Resources