2

In my web application, I have a checkout process where the user can decide whether he wants to login or not. The process is the same, but with the login the data in the checkout process gets prefilled.

shopping cart --> continue with/without login --> checkout

I know how to "secure" specific pages with the container managed login, but how to I implement an "optional login"? I searched the internet long time, but only found the conventional methods for login, unfortuneatly not what I need.

Is there a way by appending a querystring to the return value of a action method?

public  String withLogin () {
   return "checkout.xhtml?login=true";
}

public String noLogin() {
   return "checkout.xhtml";
}

Any help and ideas are appreciated.


Solution:

Based on kolossus' answer I found my solution. The authenticate-Method was what I needed but didn't found.

So I implemented a WebFilter which does the authentication based on the url paramater login=true which I return from the ManagedBean as mentioned above.

@WebFilter("/order/checkout.xhtml")
public class LoginFilter implements Filter{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        if(("true").equals(req.getParameter("login"))) {
            req.authenticate((HttpServletResponse) response);
        }       
        chain.doFilter(request, response);      
    }

    // init and destroy Method
}

Although kolossus said that one should not display the "login option" in the URL (I partly agree) I used it this way anyway, because the user can decide if he wants to login or not on his own (by clicking a different button) and it's not a security issue.

Manuel
  • 456
  • 5
  • 20

2 Answers2

2

return "checkout.xhtml?login-needed=true";.

Don't do that. Just don't. The last thing you want displayed in a URL in human-readable text is an option to login or not.

Optional login in your case means two things:

  1. Removing the checkout page from the global security realm of your application
  2. Use Servlet 3.0's programmatic login to manually manage the authentication of the checkout page. Programmatic login provides the following methods to handle authentication

    • login() will allow you hand-feed user credentials to your configured realm. With this, you can perform the authentication in a preRenderView event on the destination page.

    • authenticate() will allow you use the configured form in your <form-login-config> to execute the check. The downside (IMO) is that this sits best outside of JSF, in a Filter probably.

So removing the checkout from the security constraint allows you to manually authenticate based on some condition.

The only thing left is how to communicate to the checkout page that authentication is or isn't required. You need to come up with a more creative way, maybe hashing an unreadable value into the GET request to represent the login state in either case. Definitely don't just say "login=yes"

In the context of your question, these may also interest you

Community
  • 1
  • 1
kolossus
  • 19,953
  • 3
  • 45
  • 94
  • thank you for your answer. But, why shouldn't I display e.g. "login=true" in the url? the user can decide if he wants to login anyway, so it makes to difference... – Manuel May 12 '13 at 08:30
  • @Manuel, I'm not saying the user shouldn't decide his preference by clicking a different button, what I'm saying is that the parameter name you've chosen is readable in the browser's address bar and exposes your implementation details to the naked eye. I'm recommending here that you obfuscate the parameter name and value so that the average user cannot make sense of it. Hash some variable into a seemingly meaningless parameter to look like `?rand=r234u2yf9393yyry3aa1kv` won't make sense to a user and they'd be less likely to want to tamper with your authentication mechanism – kolossus May 12 '13 at 15:04
0

I would consider using spring security and granting access to your pages for anonymous users. Then hide specific components if the user is anonymous.

Community
  • 1
  • 1
dratewka
  • 2,094
  • 11
  • 15
  • Thanks for you answer, but I think you understood me wrong. I will let the user decide whether he wants to login or not and display the login form if he wants to login (and redirect after login to the page where he wanted to go). Also, unfortunately it's not possible to use spring in our project... – Manuel May 11 '13 at 13:23
  • Ok, I thought you wanted to extend the functionality if the user's logged in. – dratewka May 11 '13 at 13:37