4

I'm trying to use WebFilter with JSF 2, but my filter not is working. The urlPattern is not recognized.

My Filter class:

@WebFilter(urlPatterns = {"/rws/*"})  
public class AuthorizationFilter implements Filter {  

    @Override  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {      
        HttpServletRequest req = (HttpServletRequest) request;  
        HttpSession session = req.getSession(true);  
        Object o = session.getAttribute("user");  
        HttpServletResponse res = (HttpServletResponse) response;  

        if(o == null)   
            res.sendRedirect(req.getContextPath() + "/login.xhtml");  
        else
            chain.doFilter(request, response);  
    }  

    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {  

    }  

    @Override  
    public void destroy() {  
    }  
}  

In my structure I want to protect all pages that are in the rws folder, but I could not configure the filter.

I've tried @ WebFilter ("/ rws / *") @ WebFilter ("/ faces / rws / *")

My filter never is executed!!

I noticed that the url does not change when I browse pages. For example, the user opens the index.xhtml performs login and then redirects to page loginOk.xhtml. LoginOk.xhtml page has links to pages that are in the folder rws.

When I click the link url does not change, ie, I'm browsing in a folder page rws but the url in the browser remains the same (http://jsftest.com:8080/TestePrimeFaces/faces/loginOK.xhtml). Is that the problem?

Used a commandLink as link, do not know if it is the most suitable. Does anyone know where is the problem?

user1352652
  • 425
  • 1
  • 8
  • 21
  • Ok, this is because I edited the code to get smaller. The problem is that the class is not executed. – user1352652 Apr 24 '13 at 13:23
  • You do not suppress annotation scanning with a web.xml: ` – Joop Eggen Apr 24 '13 at 13:52
  • I did not understand your first question. If I mapping /* all requests pass through the filter – user1352652 Apr 24 '13 at 16:07
  • (1) As `/*` works that point is moot. (One could have suppressed `@WebFilter` scanning with `metadata-complete="true".) (2) If war is called xxx.war, try `/xxx/rws/*` (context root). – Joop Eggen Apr 24 '13 at 17:00
  • Possible duplicate of [filter-mapped-on-forward-dispatcher-isnt-invoked-when-jsf-navigation-is-perform](http://stackoverflow.com/questions/11187934/filter-mapped-on-forward-dispatcher-isnt-invoked-when-jsf-navigation-is-perform) – Ravi Kadaboina Apr 24 '13 at 18:18
  • AFAIK WebFilter annotation needs Application class to be annotated with @ServletComponentScan in order to work – spekdrum May 11 '23 at 13:59

2 Answers2

6

add "@Component" like this.

@Component
@WebFilter(urlPatterns = {"/rws/*"})  
public class AuthorizationFilter implements Filter { ...
helong
  • 61
  • 1
  • 2
1

Servlet filters don't get triggered when you perform a non-redirect JSF navigation on postback. JSF navigation does namely by default not create a new HTTP request (which would trigger the filter), but it just changes the content of the HTTP response while still keeping the same HTTP request (that's also exactly why you don't see a change in browser's address bar).

Adding the FORWARD dispatcher to the filter mapping as some may suggest won't work as JSF on Facelets doesn't use RequestDispatcher#forward() unlike "plain" JSP/Servlet and many other MVC frameworks.

If you want to trigger the filter, just send a new request by a redirect.

So, instead of

public String login() {
    // ...

    return "home";
}

just do

public String login() {
    // ...

    return "home?faces-redirect=true";
}

If you worry about faces messages being lost due to the redirect, just make use of the flash scope.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks, I'll try that and post the result here. I do not understand what you said at the end of your post, can you explain better, please? "If you worry about faces messages being lost due to the redirect, just make use of the flash scope." – user1352652 Apr 25 '13 at 01:51
  • If you're using `FacesContext#addMessage()` in combination with a redirect, then they won't show up in the redirected page. But if you're not adding any faces messages at all, just ignore that part of the answer :) See also the 3rd link in the "See also" list for a related question&answer about that. I was just adding it for the sake of completeness. Perhaps you were using `context.addMessage(new FacesMessage("You're successfully logged in!"))` or so, which could possibly be exactly the reason why you don't want to send a redirect in first place. – BalusC Apr 25 '13 at 01:53
  • Another question, whats better in this case? WebFilter or PhaseListener? I think that PhaseListener overloads the app server. – user1352652 Apr 25 '13 at 01:54
  • A servlet filter is definitely better. A phase listener is tightly coupled to JSF and doesn't cover non-JSF requests. Authorization should absolutely be done on a per HTTP-request basis, not on a per JSF-view basis. – BalusC Apr 25 '13 at 01:55