Reputation: 812
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
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