Actually I'm new to JSF and Facelets and enterprise apps despite i've been working on it the last 4 months, anyway, i'm developing a web page which has a login, an user administrator and a documents administrator (it has more but it doesn't matter) and i have to manage the acces and the content of pages according to each user permissions. Reading about security i've found out many ways of doing a login, but i have made my own with Stateful Beans in order to maintain the users data in the application for using them later so i can restrict the content. the question is... is this the correct way to manage the content according to users restrictions?
if not, which is the best and securest way of doing it?
this is my Stateful Bean (i did not include the Getters and Setters)
#ManagedBean
#Stateful
public class HandlerLogin implements Serializable{
#EJB
private LoginMethodsLocal loginMethods;
private String loginNickname;
private String loginPassword;
private String userData[];
//[0]=Nickname
//[1]=Name
//[2]=User Type
private boolean loguedIn= false;
public void check(){
System.out.println(this.loginNombre);
System.out.println(this.loginContrasena);
this.userData= loginMethods.Login(this.loginNickname, this.loginPassword);
//the method loginMethods.Login() queries in the database looking for
//"this.loginNickname" and "this.loginPassword"
if (this.userData!=null){
this.loguedIn=true;
}
else{
this.loguedIn= false;
FacesContext.getCurrentInstance().addMessage("mensajesLogin", new FacesMessage("Error, User Does not Exist"));
}
}
public void closeSession(){
this.userData=null;
}
}
so my logic to manage the content and navigation is to check what kind of user is and depending on it determine how the acces and rendering is going to be
The #Stateful annotation does nothing in a JSF #ManagedBean. That annotation is only really been used when the class is by itself injected as #EJB in another managed bean or EJB and even then, a brand new and completely different instance with all properties set to default would have been created and used. So the #Stateful annotation definitely doesn't do what you think it does. Remove it, it makes no sense in this context.
Whether the remaining code is the correct way or not depends on the concrete functional requirements. There are many ways which are equally good and secure (assuming that you understand what code you actually are writing). The question is more: how many of the wheel do you want to reinvent yourself? The builtin container managed authentication leaves very little room for finegrained control, but if it is sufficient for you, then just make use of it instead of homebrewing the authentication yourself.
Going through the following related answers should give some good ideas:
Performing user authentication in Java EE / JSF using j_security_check
JSF: How control access and rights in JSF?
How to check if is user logged in?
How to properly use isUserInRole(role)
JSF request scoped bean keeps recreating new Stateful session beans on every request?
Related
Do you think it is a good idea to put all widely used utility methods in an application scoped bean?
In the current implementation of the application I'm working on, all utility methods (manipulating with Strings, cookies, checking url, checking current page where the user is etc.) are all put in one big request scoped bean and they are referenced from every xhtml page.
I couldn't find any information on stackoverflow if the approach of putting utility methods in an application scoped bean would be a good or a bad choice.
Why I came across this idea is the need of reusing those methods in a bean of a wider scope then a request scoped bean (like view or session scoped bean). Correct me if I'm wrong but you should always inject same or wider scoped beans i.e. you shouldn't inject request scoped bean inside a view scoped one.
I think using utility methods from application scoped bean should be beneficial (there won't be any new object creations, one object will be created and re-used across all application), but still I would like a confirmation or someone to tell me if that is a wrong approach and why is it wrong.
As to the bean scope, if the bean doesn't have any state (i.e. the class doesn't have any mutable instance variables), then it can safely be application scoped. See also How to choose the right bean scope? This all is regardless of the purpose of the bean (utility or not). Given that utility functions are per definition stateless, then you should definitely be using an application scoped bean. It saves the cost of instantiating on every single request.
As to having utility methods in a managed bean, in object oriented perspective this is a poor practice, because in order to access them from EL those methods cannot be static while they should be. You can't use them as real utility methods in other normal Java classes. Static code analyzers like Sonar will mark them all with a big red flag. This is thus an anti-pattern. The correct approach would be to keep using a true utility class (public final class with private Constructor() with solely static methods) and register all those static methods as EL functions in your.taglib.xml as described in How to create a custom EL function to invoke a static method?
At least, this is what you should be doing when you intend to have a publicly reusable library such as JSTL fn:xxx(), PrimeFaces p:xxx() or OmniFaces of:xxx(). If you happen to use OmniFaces, then you could, instead of creating a your.taglib.xml file, reference the class in <o:importFunctions>. It will automatically export all public static methods of the given type into EL function scope.
<o:importFunctions type="com.example.Utils" var="u" />
...
<x:foo attr="#{u:foo(bean.property)}" />
If you don't use OmniFaces, and this all is for internal usage, then I can imagine that it becomes tiresome to redo all that your.taglib.xml registration boilerplate for every tiny utility function which suddenly pops up. I can rationalize and forgive abusing an application scoped bean for such "internal usage only" cases. Only when you start to externalize/modularize/publicize it, then you should really register them as EL functions and not expose poor practices into public.
I have a #ManagedBean #SessionScoped class to represent a user session. Assume it has a theoretical method doHorribleThings(). Access to methods of this bean through JSF can, for example, be enabled through Expression Language attributes such as action="#{userSession.doHorribleThings()}" on a Prime Faces p:commandButton.
My question is, does JSF manage access security for such method? Can a user issue performing the action of a button that is not being rendered for him, e.g. by sending an artificial HTTP package? Or does JSF capsulate a virtual client desktop that stretches accross the network, effectively enabling access control through GUI design?
No, JSF doesn't have an access security for invoking a method in a managedbean other than the UI, as far as I know.
Because if your able to mimic an action that happens through the click of a JSP/Primefaces button with a manual HTTP request then JSF container cannot identify the difference between the two and hence work the same way for both the request
I know there's a lot of debate on using stateful vs stateless EJBs in web applications.
The shopping cart is the most common use case: Oracle's Java EE examples use it a lot in the official docs, too.
Here on stackoverflow I found many interesting answers like this The Shopping Cart dilemma in JavaEE which often say something like:
ok... SFSB are good in enterprise, complex scenarios, e.g. if you want to share them with other applications and make them available not only to JSF/web clients
but... if you're just developing your grandpa's e-commerce website, just stick to the HttpSession / SessionScoped cdi-managed bean, and write your business methods in SLSB, as they are more efficient, and so on...
However, because I'm still in a learning and discovery phase, I just want to give SFSB a try, by myself, trying to build a simple shopping cart.
I saw an interesting tutorial suggesting to store a JNDI-retrieved instance of the #Stateful shopping cart ejb interface in the HttpSession, the first time the web client needed it, then use it as usual, during the web session. In my JSF presentation layer, I suppose I would have a #SessionScoped #Named bean (let's call it ShopController), and, in its initialization, store one instance of the stateful ejb in an instance variable.
I wonder if it's possible to directly bind the #Stateful bean to the http session by annotating it with the #SessionScoped CDI annotation.
Will it work as described above? Will CDI create one SFSB for each web session?
#SessionScoped is for #Named beans and #Stateful is for #EJB beans. If I'm not wrong, you cannot annotate 1 bean with both. If you want to use #Stateful, just annotate your ShoppingCart bean with #EJB and #Local and then reference it in your ShopController. Something like this:
#Named
#SessionScoped
public class ShopController {
...
#EJB
private ShoppingCart cart;
...
// Getters and Setters
}
#Local
#Stateful
public class ShoppingCart {
...
}
Don't waste your time learning how to use SFSB for web applications. You will have scalability issues very soon. Why would you learn how to make an application that uses unnecessary server resources?
Even your managed beans shouldn't be SessionScoped. At most create only one very thin SessionScoped MB with small user data to track it and all others should be request, view scoped.
The answer to your question is yes, you can use CDI to bind SessionScoped MB to SFSB EJBs. But this is not a nice architecture for web applications.
I'm working on a JSF (v1.2) application. In my application I need a generic servlet which could serve any resource (PDF, Images, Excel, etc). My idea is to ask the caller to send the required information so that I can find out the correct delegator class using some configurations.
This delegator class will take care of serving the correct resource.
For example this is the request url
http://example.com/servlet?delegatorid=abcd
My Servlet code is something like this.
protected void doGet(HttpServletRequest request, HttpServletResponse response){
String delegatorID=request.getParameter("delegatorid");
//Get the configuration from Configuration table
configuration=getConfiguration(delegatorID);
//invoke the method of the delegator class based on this configuration
Object result=invokeMethod(configuration);
//write the response to the stream
}
My question is what is the best way to do this in a JSF project?
Should I completely avoid JSF dependency in this operation? I can find the delegator method and class and invoke it using reflection. Will there be any potential restrictions in future if I avoid JSF dependency. [One problem which I can think about is, in one of the code, I need to get the user information from session. I'm doing this through FacesContext. Since FacesContext is not available, it will fail, I should have another option to get the session.
If I have to introduce JSF dependency, how do I get the FacesContext
here? As far as I know, only the beans that are stored in
application scope can be accessed here. I don't want to do that. Is there any other way of getting it?
Instead of using a servlet, can I do this by invoking a ManagedBean
method directly using the URL? This will give me FacesContext. I
think I need to have a dummy JSP page for the managed bean method to
get invoked.
Could you please let me your thoughts on this?
The FacesContext (and ExternalContext) is just a facade over HttpServletRequest, HttpServletResponse, HttpSession, ServletContext, etcetara along with some JSF specifics which you don't need at all in a plain vanilla servlet. The ExternalContext#getSessionMap() is nothing more than an abstract mapping of HttpSession#get/setAttribute().
In a plain vanilla servlet, the session is just available by request.getSession() and the application by getServletContext() the usual way. See also among others this related question: Get JSF managed bean by name in any Servlet related class.
You can also just refactor code which needs to be shared by JSF and Servlet into an utility method which doesn't have any dependencies on javax.faces.* nor javax.servlet.* classes (or at most only javax.servlet.*) and finally let the callers each pass the necessary information through.
Implementing a simple Login screen using JSF and Spring and Hibernate. I have written the Service and Data Layer Beans in Spring and integrated them with Hibernate.
I defined a Sign Up (new User creation) screen with two fields user id, password in JSF and wired them to a Managed Bean. (Bean Name: Users) Here this bean is also the domain class.
Now on click of the create button in JSF view I need to call the Service Bean methods (which are spring beans). For this I see that I have two ways to do,
Write a method in Users managed bean that takes the given user, password and calls the spring service bean methods which in turn calls DAO bean methods for saving data in DB. But here my question is how far it is a good practise to write controller kind of method in Domain classes?
Second way is to define a new Managed Bean that has the Spring Service object as a property (Which is injected using spring+jsf integration) and a method to call the service bean methods.
Am I doing a correct design? Any thing wrong? Please suggest me for a better design.
Thanks
Dont make your domain class as jsf managed bean.
Generally what I follow is I encapsulate domain class and other UI supporting properties in a form bean(when scenario is complex else direct entity as a property in managed bean) and have it in managed bean.
Spring service is injected in managed bean and on action form bean/entity bean is passed to spring service for business/use case processing and persistence(dao/repository).
Template Code:
#ManagedBean
public class Bean{
private Entity entity;//or
private FormBean formBean;
#Inject private Service service;
public String doAction(){
//error processing from service layer and UI message handling
service.process(entity);//or
service.process(formBean);
return Navigation.Constant;
}
}
Managed bean purpose should be to collect view data and pass it to service for processing. If you make your domain/entity class as managed bean you will be coupling it with JSF library which is not good for reusability. As per design principle SRP(single responsibility principle), class should have one responsibility in that case it will have more and hence as mentioned above not good practice.
Point 2 as mentioned by you is better.
Hope this helps !!!!