[SPRING] Spring의 인증 필터 내에서 서비스를 자동 응답 할 수 없습니다.
SPRINGSpring의 인증 필터 내에서 서비스를 자동 응답 할 수 없습니다.
토큰으로 사용자를 인증하려고하지만 AuthenticationTokenProcessingFilter 내부에서 내 서비스를 자동 연결하려고하면 null 포인터 예외가 발생합니다. autowired 서비스가 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);
}
}
나는 내 App Config에서 다음을 추가하려고 시도했다.
@Bean(name="myServices")
public MyServices stockService() {
return new MyServiceImpl();
}
내 AppConfig 주석은 다음과 같습니다.
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.marketplace")
public class AppConfig extends WebMvcConfigurerAdapter {
해결법
-
==============================
1.필터의 종속성 삽입은 즉시 사용할 수 없습니다. GenericFilterBean을 사용하더라도 Servlet Filter는 봄에 관리되지 않습니다. javadocs에서 언급했듯이
필터의 종속성 삽입은 즉시 사용할 수 없습니다. GenericFilterBean을 사용하더라도 Servlet Filter는 봄에 관리되지 않습니다. javadocs에서 언급했듯이
평범한 영어로 봄이 서비스를 주입 할 것으로 기대할 수는 없지만 첫 번째 호출에서 스프링을 설정하는 것이 좋습니다. 예 :
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 ... } }
-
==============================
2.방금 추가하여
방금 추가하여
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (this);
명시적인 한정자를 추가하려고 할 때도 왜 이렇게해야하는지 확신 할 수 없습니다. 이제 코드는 다음과 같이 보입니다.
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")) {
-
==============================
3.그것은 충분히 오래된 질문이지만, 나는이 문제를 저에게 좋아하는 사람들을 위해 대답을 추가 할 것입니다.
그것은 충분히 오래된 질문이지만, 나는이 문제를 저에게 좋아하는 사람들을 위해 대답을 추가 할 것입니다.
GenericFilterBean에서 필터를 상속 받아 Spring @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; } }
이렇게하면 필터에서 구성 요소가 올바르게 자동 작성됩니다.
-
==============================
4.필터 클래스가 GenericFilterBean을 확장하면 다음과 같이 앱 컨텍스트에서 Bean에 대한 참조를 얻을 수 있습니다.
필터 클래스가 GenericFilterBean을 확장하면 다음과 같이 앱 컨텍스트에서 Bean에 대한 참조를 얻을 수 있습니다.
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"); }
-
==============================
5.빈 필터를 구성하고 필요한 매개 변수로 전달할 수 있습니다. 스프링 컨텍스트가 필터인지, 스프링의 자동 스캔이 의존성 주입을 얻을 수 없는지 알고 있습니다. 하지만 100 % 확실한 주석이 있다면 필터에 넣어서 마법 같은 것들을 할 수는 없습니다.
빈 필터를 구성하고 필요한 매개 변수로 전달할 수 있습니다. 스프링 컨텍스트가 필터인지, 스프링의 자동 스캔이 의존성 주입을 얻을 수 없는지 알고 있습니다. 하지만 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>
bean을 spring.xml에 삽입한다.
<bean id="YourFilter" class="com.YourFilter"> <property name="param"> <value>values</value> </property> </bean>
from https://stackoverflow.com/questions/32494398/unable-to-autowire-the-service-inside-my-authentication-filter-in-spring by cc-by-sa and MIT license