Home > Software design >  How do I load a bean from within a Spring custom Authentication Provider
How do I load a bean from within a Spring custom Authentication Provider

Time:01-19

Can anyone advise how I might retrieve the settings bean from within the method:

protected void additionalAuthenticationChecks(UserDetails userDetails,
        UsernamePasswordAuthenticationToken authentication)
        throws AuthenticationException

Inside a custom Authentication Provider in Spring?

I am currently learning Spring security as I work on some assigned software.

I am making some adjustments to a Spring custom Authentication Provider that inherits from LdapAuthenticationProvider.

As part of the code, I want to retrieve some settings from a custom bean that is described in my applicationContext.xml thus:

<bean name="mySettings" ></bean>

This allows me to retrieve settings that are specified in the properties file which is identified by the context:property-placeholder tag in applicationContext.xml thus:

<context:property-placeholder location="classpath:mySettings.properties" />

Ordinarily, I pull this bean in when I need the data it contains like so:

WebApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
MySettingsBean mySettings = (MySettingsBean) ctx.getBean("mySettings");       

However, when I put this code to retrieve the bean in the method:

protected void additionalAuthenticationChecks(UserDetails userDetails,
        UsernamePasswordAuthenticationToken authentication)
        throws AuthenticationException

in my Spring custom Authentication Provider that inherits from LdapAuthenticationProvider in order to overrides the method of the same name, I get an exception thus:

org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [default] in context with path [/ice] threw exception
    java.lang.IllegalArgumentException: FacesContext must not be null
    at org.springframework.util.Assert.notNull(Assert.java:134)
    at org.springframework.web.jsf.FacesContextUtils.getWebApplicationContext(FacesContextUtils.java:50)

Indicating that the line

WebApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());

Is failing due to a lack of a FacesContext.

Thanks heaps

David :-)

CodePudding user response:

I figured it out.

There are two different (but similar) methods for retrieving the beans in Spring.

One way is to add the ApplicationContext to the class where you need it using an @Autowired annotation thus:

import org.springframework.context.ApplicationContext;
...

class MyClassThatNeedsAppContext {

    @Autowired
    private ApplicationContext appContext;
...
}

Then, at the point where you need the bean, you can get it using this code:

MySettingsBean mySettings = this.appContext.getBean(MySettingsBean.class);

The other method is similar (and dispenses with the whole FacesContextUtils static method call).

You add an Autowired reference to the WebApplicationContext thus:

import org.springframework.web.context.WebApplicationContext;
...

...

class MyClassThatNeedsAppContext {

    @Autowired
    private WebApplicationContext webContext;
    ...
}

And then when you need the bean, you can retrieve it thus:

MySettingsBean mySettings = (MySettingsBean) this.webContext.getBean("mySettings");

This method works just fine in the middle of a custom AuthenticationProvider. I suspect (but have not yet tested) that it would work anywhere in the application.

  • Related