I want to create and share a JSF-StrutsAuthenticator, but I need your comments and suggestions.
The idea? well, with this frameworks (jsf, strust, etc) it is "very" difficult to use <Basic> and <Form> authenticators. And generally, each programmer use his/her way to do authentication.
I am wonder (and here your programmer opinions are extremely important) if we could standard, for this project, a way to pass "login", "password" and other parameters, to the Filter.
I am thinking in three ways to do that (improvements and others suggestions/ideas are welcome).
1. In the page (jsf, jsp, html, etc) use request.setParameter(key, value). These three keys could be the same as FormAuthenticator: "j_username"; "j_password"; "j_rememberme";
2. In the Action (Struts) or in the Bean (JSF) use request.getSession.setAttribute(key, value). The three keys will be the same as before.
3. Use an object stored at the session. The steps will be:
3.1 The filter, set an object that contains the three keys using request.getSession.setAttribute("obj", obj)
3.2 This object is populated by the Bean or Action: obj.setLogin, obj.setPassword, obj.setRememberMe
3.3 The filter, for each doAction(), ask if this object is populated and authenticate the user.
Regards
Vladimir.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm not sure why you think that app frameworks are difficult to use with sf... I ust Struts 1.x without a problem. Any decent framework should cooperate with the servlet specification's standard container-managed authentication and authorization mechanism (which sf implements as closely as possible).
Can you describe what you believe does not work?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Chris, specifically in JSF, it is a problem to do login or logout process based in request.getURI or request.getPathInfo because JSF (generally) perform an internal forward to some page (see http://wiki.apache.org/myfaces/FAQ#StaleLink for more information). That means, the Browser or filter shows a link to the previous page.
Because of that, I am thinking that processLogin or processLogout in the JSFAuthenticator must perform an authentication based in attributes or parameters (stored in Session or in the Request) instead of search a pattern of a page.
What do you think?
Regards.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This shouldn't be a problem: filters can be configured to run (or not run) on internal redirects as well as "normal" requests.
Is there a demonstrable problem that I can observe? I'm having trouble visualizing the problem you're trying to overcome, which is why I'm not sure how to help.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The 1st problem is: JSF (h:form) component does not allow to use j_security_check action.
Of course, if you use a jsp page, with normal html "form" tag, sf.. works great !!
To authenticate, I need to get (in some way) username and password. In the first post, I suggest some methods to do that. Like I said, sadly I can not use FORM or BASIC authentication in pure jsf.
The 2nd problem (and you give me a possible solution) is to get this parameters from login page. JSF works with forward request, but I will try to use the dispatcher tag.
Thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hmm... looking at the documentation for h:form, I'm not even sure how you set the action of the form in general. Is it possible to simply use a regular <form> tag manually for the login form? Or, is there another URL you can use, other than j_security_check? SF allows you to use a different URI for "j_security_check" if you want to. Simply set the "loginSubmitPattern" init-param on the filter to something other than "/j_security_check" (which is the default).
What authentication and authorization mechanism does JSF usually work with? I would imagine that JSF works properly with the servlet specification which mandates things like j_security_check as the URI for authentication.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
A JSF h:form does not allow to call this or another CGI security checks. Of course, you can use JAAS (or other kind of) "Authorization" frameworks without any problem. Just for authentication issues is different.
In this situation, you would suggest:
1. develop some kind of JSFAuthenticator
2. other idea (unfortunately without change login.jsp to use html <form> tag)
3. not use the security filter
In my opinion, create a JSFAuthenticator is interesting but not a <Basic-Form>Authenticator standard.
Thanks Chris
Regards
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
To answer your further questions, I'm not sure how a JSFAuthenticator would work, given that you want to invoke it directly and not really use it as it was intended. If I were you, I'm not sure I would even bother using SF if all of this is really true.
I've never had anyone else ask questions about JSF... maybe that's because nobody uses JSF with SF, but I can't imagine why JSF would essentially prohibit the use of the standard container-managed authentication.
SF can be used with JAAS, but you say that only the authorization works, not the authentication. That seems odd.
SF is not magic... all it does is grab the credentials from the request, validate them against a realm, and put a Principal object in the session such that HttpServletRequest.getPrincipal returns it. Since you are trying to invoke the authenticator yourself (it seems), you could avoid writing a JSFAuthenticator and simply call the realm directly. Then, create your own Principal object and put it into the session using the proper session key that SF uses. In this way, SF would not handle the login, but would perform the authorization.
Given all this complexity and skirting around the filter, why do you want to use SF at all? SF's features that make it attractive are almost entirely in the parts that you are skipping.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
JSF is a templating framework, one of many and not the best one.
So if we want to use JSF with SF we have to create our own tag, as JSF specs state. Simply extend <h:form/> and make <h:sf-login-form/>. And you will have all what d.u. need there. JSF is an extensible framework and it should be extended in this case.
I feel like you are trying to go against the JSF grain, that will cause you some problems.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is true, we could extend h:form and perform the authentication using FORMAuthenticator.
But, I saw that Chris comments some important issue. "SF is not magic... all it does is grab..." Well, that is exactly how JSFAuthenticator could work. That means, in processLogin method, you:
1. verify if request came from login.jsf page
2. obtain (from request parameters) j_username and j_password
3. execute exactly as FormAuthenticator do.
The 2nd point is different than the others authenticators. You will have to iterate from httpRequest.getParameterNames() to find the key that match j_username and j_password. With this key, you can obtain the value of these parameters httpRequest.getParameterValues(key).
BTW, I like JSF (just a little bit more than Struts)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So far I can see that you don't like to look for a j_username and j_password in the request.
If it is the only thing that bother you, put a filter and traverse these parameters whenever you want it.
If you want to go to extreme you can implement your own way of logging in, have a look at (http://loud-thoughts.blogspot.com/2006/11/josso-automatic-user-login-filter.html) and do something similar.
But frankly I am missing the point.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi developers
I want to create and share a JSF-StrutsAuthenticator, but I need your comments and suggestions.
The idea? well, with this frameworks (jsf, strust, etc) it is "very" difficult to use <Basic> and <Form> authenticators. And generally, each programmer use his/her way to do authentication.
I am wonder (and here your programmer opinions are extremely important) if we could standard, for this project, a way to pass "login", "password" and other parameters, to the Filter.
I am thinking in three ways to do that (improvements and others suggestions/ideas are welcome).
1. In the page (jsf, jsp, html, etc) use request.setParameter(key, value). These three keys could be the same as FormAuthenticator: "j_username"; "j_password"; "j_rememberme";
2. In the Action (Struts) or in the Bean (JSF) use request.getSession.setAttribute(key, value). The three keys will be the same as before.
3. Use an object stored at the session. The steps will be:
3.1 The filter, set an object that contains the three keys using request.getSession.setAttribute("obj", obj)
3.2 This object is populated by the Bean or Action: obj.setLogin, obj.setPassword, obj.setRememberMe
3.3 The filter, for each doAction(), ask if this object is populated and authenticate the user.
Regards
Vladimir.
I'm not sure why you think that app frameworks are difficult to use with sf... I ust Struts 1.x without a problem. Any decent framework should cooperate with the servlet specification's standard container-managed authentication and authorization mechanism (which sf implements as closely as possible).
Can you describe what you believe does not work?
Chris, specifically in JSF, it is a problem to do login or logout process based in request.getURI or request.getPathInfo because JSF (generally) perform an internal forward to some page (see http://wiki.apache.org/myfaces/FAQ#StaleLink for more information). That means, the Browser or filter shows a link to the previous page.
Because of that, I am thinking that processLogin or processLogout in the JSFAuthenticator must perform an authentication based in attributes or parameters (stored in Session or in the Request) instead of search a pattern of a page.
What do you think?
Regards.
This shouldn't be a problem: filters can be configured to run (or not run) on internal redirects as well as "normal" requests.
Is there a demonstrable problem that I can observe? I'm having trouble visualizing the problem you're trying to overcome, which is why I'm not sure how to help.
Hi Chris,
The 1st problem is: JSF (h:form) component does not allow to use j_security_check action.
Of course, if you use a jsp page, with normal html "form" tag, sf.. works great !!
To authenticate, I need to get (in some way) username and password. In the first post, I suggest some methods to do that. Like I said, sadly I can not use FORM or BASIC authentication in pure jsf.
The 2nd problem (and you give me a possible solution) is to get this parameters from login page. JSF works with forward request, but I will try to use the dispatcher tag.
Thanks
Hmm... looking at the documentation for h:form, I'm not even sure how you set the action of the form in general. Is it possible to simply use a regular <form> tag manually for the login form? Or, is there another URL you can use, other than j_security_check? SF allows you to use a different URI for "j_security_check" if you want to. Simply set the "loginSubmitPattern" init-param on the filter to something other than "/j_security_check" (which is the default).
What authentication and authorization mechanism does JSF usually work with? I would imagine that JSF works properly with the servlet specification which mandates things like j_security_check as the URI for authentication.
A JSF h:form does not allow to call this or another CGI security checks. Of course, you can use JAAS (or other kind of) "Authorization" frameworks without any problem. Just for authentication issues is different.
In this situation, you would suggest:
1. develop some kind of JSFAuthenticator
2. other idea (unfortunately without change login.jsp to use html <form> tag)
3. not use the security filter
In my opinion, create a JSFAuthenticator is interesting but not a <Basic-Form>Authenticator standard.
Thanks Chris
Regards
What /does/ <h:form> allow you to do?
To answer your further questions, I'm not sure how a JSFAuthenticator would work, given that you want to invoke it directly and not really use it as it was intended. If I were you, I'm not sure I would even bother using SF if all of this is really true.
I've never had anyone else ask questions about JSF... maybe that's because nobody uses JSF with SF, but I can't imagine why JSF would essentially prohibit the use of the standard container-managed authentication.
SF can be used with JAAS, but you say that only the authorization works, not the authentication. That seems odd.
SF is not magic... all it does is grab the credentials from the request, validate them against a realm, and put a Principal object in the session such that HttpServletRequest.getPrincipal returns it. Since you are trying to invoke the authenticator yourself (it seems), you could avoid writing a JSFAuthenticator and simply call the realm directly. Then, create your own Principal object and put it into the session using the proper session key that SF uses. In this way, SF would not handle the login, but would perform the authorization.
Given all this complexity and skirting around the filter, why do you want to use SF at all? SF's features that make it attractive are almost entirely in the parts that you are skipping.
My 2 cents ...
JSF is a templating framework, one of many and not the best one.
So if we want to use JSF with SF we have to create our own tag, as JSF specs state. Simply extend <h:form/> and make <h:sf-login-form/>. And you will have all what d.u. need there. JSF is an extensible framework and it should be extended in this case.
I feel like you are trying to go against the JSF grain, that will cause you some problems.
Ivan and Chris
It is true, we could extend h:form and perform the authentication using FORMAuthenticator.
But, I saw that Chris comments some important issue. "SF is not magic... all it does is grab..." Well, that is exactly how JSFAuthenticator could work. That means, in processLogin method, you:
1. verify if request came from login.jsf page
2. obtain (from request parameters) j_username and j_password
3. execute exactly as FormAuthenticator do.
The 2nd point is different than the others authenticators. You will have to iterate from httpRequest.getParameterNames() to find the key that match j_username and j_password. With this key, you can obtain the value of these parameters httpRequest.getParameterValues(key).
BTW, I like JSF (just a little bit more than Struts)
Vladimir,
I still don't understand why you can't predict the URL that will be used for login submission.
It sounds like you are doing much more work than necessary.
I'm not convinced that a JSFAuthenticator will be a useful addition to SF, but you are free to maintain your own extensions to SF on your own.
Good luck,
-chris
So far I can see that you don't like to look for a j_username and j_password in the request.
If it is the only thing that bother you, put a filter and traverse these parameters whenever you want it.
If you want to go to extreme you can implement your own way of logging in, have a look at (http://loud-thoughts.blogspot.com/2006/11/josso-automatic-user-login-filter.html) and do something similar.
But frankly I am missing the point.
Thank you people for your comments.
Regards