nespapu
nespapu

Reputation: 812

Why autowired bean is null?

TARGET

Redirect user to home page if he tries to access login page once he is already logged in.

APPROACH

Redirect user at filter level rather than in login controller.

SYSTEM DETAILS

JSF

Spring security

UrlRewriteFilter

DETAILS

Based on this link I have created a class to access spring security and ask if user is logged in (is not an anonymous user):

 public class SecurityContextAccessorImpl implements SecurityContextAccessor {

    @Autowired
    private AuthenticationTrustResolver authenticationTrustResolver;

    public SecurityContextAccessorImpl() {
    }

    @Override
    public boolean isCurrentAuthenticationAnonymous() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authenticationTrustResolver.isAnonymous(authentication);
    }
}

Then I developed a filter which uses previous class to redirect user:

@WebFilter
@Component
public class LoginFilter implements Filter {

    @Autowired
    private SecurityContextAccessor securityContextAccessor;

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

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

        if(securityContextAccessor != null){
            if(securityContextAccessor.isCurrentAuthenticationAnonymous()){
                String contextPath = ((HttpServletRequest)request).getContextPath();
                ((HttpServletResponse)response).sendRedirect(contextPath + "/ASSDA/home/home");
            }
        }

        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

Filter is defined in web.xml after spring and urlrewrite:

<!-- ============== Spring security ============= -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
<!-- ============== UrlRewriteFilter ============= -->
    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>

    </filter>
    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- ============== Login Filter ============= -->
   <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>es.assda.ged.web.controller.security.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/login.xhtml</url-pattern>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

Beans are defined in corresponding applicationContext.xml

    <beans:bean id="defaultTargetUrl" class="java.lang.String">
        <beans:constructor-arg value="/ASSDA/home/home" />
    </beans:bean>

    <beans:bean id="authenticationTrustResolver" name="authenticationTrustResolver" class="org.springframework.security.authentication.AuthenticationTrustResolverImpl" />

<bean id="securityContextAccessor" name="securityContextAccessor" class="es.assda.ged.api.security.SecurityContextAccessorImpl" />

CURRENT BEHAVIOUR

Redirection is doing well and reaching LoginFilter, but autowired securityContextAccessor variable is not being initialized. I think it is not initialized because bean authenticationTrustResolver is null.

On the other hand, if I declare autowired variable securityContextAccessor in the login controller, it is correctly injected.

Why securityContextACcessor is null in LoginFilter and correctly instantiated in login controller?

Upvotes: 0

Views: 400

Answers (1)

gpeche
gpeche

Reputation: 22514

It looks like you are not instantiating your Filter via Spring, so you don't get dependency injection. It should work by using DelegatingFilterProxy:

web.xml:

<filter>
   <filter-name>springLoginFilter</filter-name><!-- Your filter bean in Spring -->
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
   <filter-name>LoginFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

applicationContext.xml:

<bean id="springLoginFilter" class="es.assda.ged.web.controller.security.LoginFilter" />  

Also, see Accessing Spring beans from servlet filters and tags

Upvotes: 1

Related Questions