I am having a problem creating custom securuity filter. I intend to create a Filter which would check with the server the sessionId which is passed in the URL - for authentication & authorization. I intend to use the exiting JSF framework already in the code (like caching for sessions, etc)
For it I first define an bean which is application scoped. The faces-config.xml looks like:
<managed-bean eager="true">
<managed-bean-name>securityBean</managed-bean-name>
<managed-bean-class>com.ecom.scareer.security.SecurityBean</managed-bean-class>
<managed-bean-scope>application </managed-bean-scope>
<managed-property>
<property-name>loginBD</property-name>
<value>#{loginBD}</value>
</managed-property>
</managed-bean>
and then define a class called SecurityBean as:
public class SecurityBean implements Serializable {
// attributes
private LoginBD loginBD;
public void setLoginBD(LoginBD loginBD) {
this.loginBD = loginBD;
}
public UserSession getUserSessionById(String sessionId) throws InvalidSessionException{
// get the session id
UserSession us = loginBD.getSession(sessionId);
return us;
}
}
and I have a filter as :
public class SecurityFilter implements Filter{
private ServletContext servletContext;
// --------------- overridden method for Filter interface ---------------
public void init(FilterConfig filterConfig) throws ServletException {
servletContext = filterConfig.getServletContext();
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Map<String, String[]> paramMap = request.getParameterMap();
FacesContext facesContext = getFacesContext(request, response);
// get the application bean for security
SecurityBean sb = (SecurityBean)getApplicationBean("securityBean", facesContext);
// values needed from the parameter
String[] vals = paramMap.get("accountId");
String accId = (vals != null && vals.length > 0)? vals[0] : null;
System.out.println("Account id .................. = " + accId);
String[] sessionIds = paramMap.get("sessionId");
String sessionId = (sessionIds != null && sessionIds.length > 0)? sessionIds[0] : null;
System.out.println("The session ...................... = " + sessionId);
try {
UserSession us = sb.getUserSessionById(sessionId);
} catch (InvalidSessionException e) {
System.out.println("Invalid session exception ");
e.printStackTrace();
}
chain.doFilter(request, response);
}
public void destroy() {
// do nothing
}
// --------------- for fetching the FacesContext
// You need an inner class to be able to call FacesContext.setCurrentInstance
// since it's a protected method
private abstract static class InnerFacesContext extends FacesContext {
protected static void setFacesContextAsCurrentInstance(FacesContext facesContext) {
FacesContext.setCurrentInstance(facesContext);
}
}
private FacesContext getFacesContext(ServletRequest request, ServletResponse response) {
// Try to get it first
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext != null) return facesContext;
FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
// Either set a private member servletContext = filterConfig.getServletContext();
// in you filter init() method or set it here like this:
// ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();
// Note that the above line would fail if you are using any other protocol than http
// Doesn't set this instance as the current instance of FacesContext.getCurrentInstance
facesContext = contextFactory.getFacesContext(servletContext, request, response, lifecycle);
// Set using our inner class
InnerFacesContext.setFacesContextAsCurrentInstance(facesContext);
// set a new viewRoot, otherwise context.getViewRoot returns null
UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "yourOwnID");
facesContext.setViewRoot(view);
return facesContext;
}
/**
*
* The method fetches the application bean for the given bean name.
* The object returned should be cast correctly to the bean
*
* @param beanName - the name of bean as described in JSF config
* @return - The bean as object. It should be cast to correct bean object before using
*/
private Object getApplicationBean(String beanName, FacesContext fContext) {
Object bean = fContext.getExternalContext().getApplicationMap().get(beanName);
return bean;
}
}
Now when I run this I get the following problems in my server:
SEVERE: Critical error during deployment:
com.sun.faces.mgbean.ManagedBeanCreationException: Unable to set property loginBD for managed bean securityBean
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:615)
at com.sun.faces.mgbean.ManagedBeanBuilder.buildBean(ManagedBeanBuilder.java:133)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:104)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:256)
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:255)
at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:4690)
at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:534)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5305)
at com.sun.enterprise.web.WebModule.start(WebModule.java:500)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:755)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1980)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1630)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:100)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:286)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:370)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1067)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1247)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1235)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:465)
at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:222)
at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)
at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:234)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
at org.springframework.web.jsf.FacesContextUtils.getRequiredWebApplicationContext(FacesContextUtils.java:83)
at org.springframework.web.jsf.el.SpringBeanFacesELResolver.getWebApplicationContext(SpringBeanFacesELResolver.java:91)
at org.springframework.web.jsf.el.SpringBeanFacesELResolver.getBeanFactory(SpringBeanFacesELResolver.java:79)
at org.springframework.beans.factory.access.el.SpringBeanELResolver.getValue(SpringBeanELResolver.java:50)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:99)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
at com.sun.faces.mgbean.BeanBuilder$Expression.evaluate(BeanBuilder.java:591)
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:606)
... 47 more
How can I get a handle to the loginBD property (defined in faces-config as property)? Is there a way to manually (through code) inject this propery? or any other way to get a handle to this?