由于web应用启动的顺序顺序的原因(listener->filter->servlet),在Filter中注入Bean是不会成功的。
网上由很多的实现方式来实现在Filter中注入Bean,这里,我换一种方式,给Filter添加一个构造方法,在初始化Filter的时候把Bean实例传入,这里以Shiro中的拦截remmeberMe的Filter为例:
package com.xibu.config.filter;
import com.xibu.dao.User;
import com.xibu.dao.UserRepository;
import com.xibu.service.UserService;
import com.xibu.utils.Const;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.OncePerRequestFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;
import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by archerlj on 2017/7/14.
*/
public class AddPrincipalToSessionFilter extends OncePerRequestFilter {
private Logger logger = LoggerFactory.getLogger(this.getClass());
//这里不使用@Autowired注入的方式。
private UserService userService;
public AddPrincipalToSessionFilter(UserService userService) {
this.userService = userService;
}
@Override
protected void doFilterInternal(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws ServletException, IOException {
Subject subject = SecurityUtils.getSubject();
if (subject.isRemembered()) {
String nameOrEmail = subject.getPrincipal().toString();
User user = userService.findByUserNameOrEmail(nameOrEmail, nameOrEmail);
if (user == null) return;
Session session = subject.getSession();
session.setAttribute(Const.LOGIN_SESSION_KEY, user);
logger.debug("Add principal to session:");
logger.debug(user.toString());
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
然后,在Shiro
的配置文件中初始化AddPrincipalToSessionFilter
:
package com.xibu.config.shiro;
import com.xibu.config.filter.AddPrincipalToSessionFilter;
import com.xibu.config.filter.KaptchaFilter;
import com.xibu.config.redis.RedisCacheManager;
import com.xibu.config.redis.RedisSessionDAO;
import com.xibu.service.UserService;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import javax.annotation.Resource;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Created by archerlj on 2017/7/9.
*/
@Configuration
public class ShiroConfiguration {
@Resource
private UserService userService;
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
//记住我过滤器
filterMap.put("rememberMeFilter", addPrincipalToSessionFilter());
shiroFilterFactoryBean.setFilters(filterMap);
......
filterChainDefinitionMap.put("/**", "rememberMeFilter,user");
...
}
private AddPrincipalToSessionFilter addPrincipalToSessionFilter() {
return new AddPrincipalToSessionFilter(userService);
}
}
最后帮朋友打个小广告