봄에 내 인증 필터 내에서 서비스를 자동 배선할 수 없음
토큰으로 사용자를 인증하려고 하는데, 내부에서 서비스를 자동으로 연결하려고 할 때AuthenticationTokenProcessingFilter
null 포인터 예외가 발생합니다.자동 배선 서비스가 null이기 때문에 이 문제를 어떻게 해결할 수 있습니까?
나의AuthenticationTokenProcessingFilter
학급
@ComponentScan(basePackages = {"com.marketplace"})
public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
@Autowired
@Qualifier("myServices")
private MyServices service;
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
@SuppressWarnings("unchecked")
Map<String, String[]> parms = request.getParameterMap();
if (parms.containsKey("token")) {
try {
String strToken = parms.get("token")[0]; // grab the first "token" parameter
User user = service.getUserByToken(strToken);
System.out.println("Token: " + strToken);
DateTime dt = new DateTime();
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime createdDate = fmt.parseDateTime(strToken);
Minutes mins = Minutes.minutesBetween(createdDate, dt);
if (user != null && mins.getMinutes() <= 30) {
System.out.println("valid token found");
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getEmailId(), user.getPassword());
token.setDetails(new WebAuthenticationDetails((HttpServletRequest) request));
Authentication authentication = new UsernamePasswordAuthenticationToken(user.getEmailId(), user.getPassword(), authorities); //this.authenticationProvider.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
}else{
System.out.println("invalid token");
}
} catch(Exception e) {
e.printStackTrace();
}
} else {
System.out.println("no token found");
}
// continue thru the filter chain
chain.doFilter(request, response);
}
}
다음을 추가하려고 했습니다.AppConfig
@Bean(name="myServices")
public MyServices stockService() {
return new MyServiceImpl();
}
내 AppConfig 주석은
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.marketplace")
public class AppConfig extends WebMvcConfigurerAdapter {
개봉 후 필터에서 종속성 주입을 사용할 수 없습니다.일반 필터를 사용하고 있지만 서블릿 필터는 봄까지 관리되지 않습니다.자바독스가 지적한 바와 같이
이 일반 필터 기본 클래스는 Spring org.springframework.context에 종속되지 않습니다.ApplicationContext 개념입니다.필터는 일반적으로 자체 컨텍스트를 로드하지 않고 필터의 ServletContext를 통해 액세스할 수 있는 Spring 루트 응용 프로그램 컨텍스트에서 서비스 빈에 액세스합니다(org.spring 프레임워크 참조).거미줄.지지하다.웹 응용 프로그램 컨텍스트 유틸리티).
쉬운 영어로 봄이 서비스를 주입하기를 기대할 수는 없지만, 첫 번째 통화에서 게으르게 설정할 수는 있습니다.예.
public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
private MyServices service;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if(service==null){
ServletContext servletContext = request.getServletContext();
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
service = webApplicationContext.getBean(MyServices.class);
}
your code ...
}
}
충분히 오래된 질문이지만, 저를 좋아하는 사람들을 위해 이 문제에 대한 제 대답을 추가하겠습니다.
다음에서 필터를 상속해야 합니다.GenericFilterBean
그리고 그것을 스프링으로 표시합니다.@Component
@Component
public class MyFilter extends GenericFilterBean {
@Autowired
private MyComponent myComponent;
//implementation
}
그런 다음 Spring 컨텍스트에 등록합니다.
@Configuration
public class MyFilterConfigurerAdapter extends WebMvcConfigurerAdapter {
@Autowired
private MyFilter myFilter;
@Bean
public FilterRegistrationBean myFilterRegistrationBean() {
FilterRegistrationBean regBean = new FilterRegistrationBean();
regBean.setFilter(myFilter);
regBean.setOrder(1);
regBean.addUrlPatterns("/myFilteredURLPattern");
return regBean;
}
}
이렇게 하면 필터의 구성 요소가 올바르게 자동으로 배선됩니다.
나는 단지 그것을 추가해서 그것을 작동시켰습니다.
춘두자동 배선 지원 프로세스현재 상황에 기반한 주입(이);
명시적 한정자를 추가하려고 시도했을 때도 우리가 왜 이것을 해야 하는지 잘 모르겠습니다. 그리고 지금 코드는 다음과 같습니다.
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
@SuppressWarnings("unchecked")
Map<String, String[]> parms = request.getParameterMap();
if (parms.containsKey("token")) {
필터 클래스가 GenericFilterBean을 확장하면 다음과 같은 방법으로 앱 컨텍스트에서 빈에 대한 참조를 얻을 수 있습니다.
public void initFilterBean() throws ServletException {
@Override
public void initFilterBean() throws ServletException {
WebApplicationContext webApplicationContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
//reference to bean from app context
yourBeanToInject = webApplicationContext.getBean(yourBeanToInject.class);
//do something with your bean
propertyValue = yourBeanToInject.getValue("propertyName");
}
하드 코딩 빈 이름을 좋아하지 않거나 둘 이상의 빈 참조를 필터에 삽입해야 하는 사용자를 위한 덜 명시적인 방법은 다음과 같습니다.
@Autowired
private YourBeanToInject yourBeanToInject;
@Override
public void initFilterBean() throws ServletException{
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, getServletContext());
//do something with your bean
propertyValue = yourBeanToInject.getValue("propertyName");
}
필요한 경우 빈 필터와 패스를 매개 변수로 구성할 수 있습니다.필터가 어디에 있는지 스프링 컨텍스트에서 알고 있습니다. 스프링의 자동 스캔처럼 의존성 주입을 받을 수 없습니다.하지만 마법 같은 것을 하기 위해 필터에 넣을 수 있는 멋진 주석이 있는지 100% 확신할 수는 없습니다.
<filter>
<filter-name>YourFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>YourFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
그런 다음 spring.xml에 콩을 주입합니다.
<bean id="YourFilter" class="com.YourFilter">
<property name="param">
<value>values</value>
</property>
</bean>
나는 파티에 늦었지만 이 해결책은 나에게 효과가 있었습니다.
web.xml.applicationContext에 ContextLoaderListener를 추가합니다.
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
그런 다음 MyFilter Spring Bean 추가자동 배선 지원 프로세스모든 종속성을 추가하는 필터에 웹 응용 프로그램 컨텍스트를 추가하는 InjectionBasedOnServletContext.
@Component
public class MyFilter implements Filter {
@Autowired
@Qualifier("userSessionServiceImpl")
private UserSessionService userSessionServiceImpl;
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain
chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) req;
if (userSessionServiceImpl == null) {
ServletContext context = httpRequest.getSession().getServletContext();
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, context);
}
.... (for brevity)
}
}
언급URL : https://stackoverflow.com/questions/32494398/unable-to-autowire-the-service-inside-my-authentication-filter-in-spring
'programing' 카테고리의 다른 글
서비스 계층 및 컨트롤러: 무엇을 담당합니까? (0) | 2023.07.26 |
---|---|
스프링 자동 배선 aop 원형 종속성 (0) | 2023.07.26 |
Angular 2의 요소에 RouterLink 또는 다른 속성 지시어를 조건부로 추가합니다. (0) | 2023.07.26 |
Swagger가 Spring Boot을 사용하여 Spring Data Rest API를 감지하지 못함 (0) | 2023.07.21 |
테이블의 CONNECT BY LEVEL이 추가 행을 반환하는 이유는 무엇입니까? (0) | 2023.07.21 |