2015-09-10 10 views
28

में मेरे प्रमाणीकरण फ़िल्टर के अंदर सेवा को स्वत: करने में असमर्थ मैं टोकन द्वारा उपयोगकर्ता को प्रमाणित करने का प्रयास कर रहा हूं, लेकिन जब मैं AuthenticationTokenProcessingFilter के अंदर अपनी सेवाओं को ऑटो तार करने का प्रयास करता हूं तो मुझे शून्य सूचक अपवाद मिलता है। क्योंकि ऑटोवायर सेवा शून्य है, मैं इस समस्या को कैसे ठीक कर सकता हूं?वसंत

मेरे 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 टिप्पणियों में follwing आज़माया गया है

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = "com.marketplace") 
public class AppConfig extends WebMvcConfigurerAdapter { 
+0

जब आप लॉग देखते हैं तो आपके बीन '' MyServices''' बनाया गया है? आप '' 'जोड़ने @ पर Component''' अपने' '' MyServices''' –

+0

हाँ मैं @ComponentScan जोड़ने और सेवा बनाया गया था की कोशिश की कोशिश कर सकते! –

+0

क्या आपके AppConfig क्लास में '@ कॉन्फ़िगरेशन' एनोटेशन है? –

उत्तर

13

मैं बस इसे बनाया है, तो यकीन है कि

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (यह) जोड़कर काम करें;

मुझे यकीन नहीं है कि हमें यह क्यों करना चाहिए जब मैंने स्पष्ट क्वालीफायर जोड़ने का प्रयास किया। और अब कोड

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")) { 
+2

आप इसे प्रत्येक doFilter() कॉल में निष्पादित किया जा रहा से रोकने के लिए @PostConstruct विधि को जोड़ने पर विचार करने के लिए। –

1

आप अपने सेम फ़िल्टर कॉन्फ़िगर और एक पैरामीटर के रूप पारित कर सकते हैं जो कुछ भी आप की जरूरत है। मैं स्प्रिंग संदर्भ से जानता हूं जहां यह फ़िल्टर है, आप निर्भरता इंजेक्शन नहीं प्राप्त कर सकते हैं कि वसंत का ऑटो-स्कैन करता है। लेकिन% नहीं 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> 
+0

आप इस मैं xml config !! –

+0

पहले एक्सएमएल यह है अपने web.xml पर (सर्वलेट conf) के साथ अच्छा नहीं हूँ के लिए जावा कॉन्फ़िग के साथ मेरी मदद कर सकते हैं और दूसरे अपने applicationContext होना चाहिए .xml (स्प्रिंग conf)। आप – paul

17

आप बॉक्स के बाहर फ़िल्टर से निर्भरता इंजेक्शन का उपयोग नहीं कर सकते हैं। यद्यपि आप जेनेरिकफिल्टरबेन का उपयोग कर रहे हैं, तो आपका सर्वलेट फ़िल्टर वसंत द्वारा प्रबंधित नहीं होता है। javadocs

द्वारा बताया गया है यह सामान्य फिल्टर आधार वर्ग स्प्रिंग org.springframework.context.ApplicationContext अवधारणा पर कोई निर्भरता है। फ़िल्टर आमतौर पर अपने स्वयं के संदर्भ को लोड नहीं करते हैं बल्कि स्प्रिंग रूट एप्लिकेशन संदर्भ से सेवा बीन्स तक पहुंचते हैं, फ़िल्टर के ServletContext के माध्यम से सुलभ ( org.springframework.web.context.support.WebApplicationContextUtils देखें)।

सादे अंग्रेजी में हम वसंत की सेवा इंजेक्ट करने की उम्मीद नहीं कर सकते हैं, लेकिन हम इसे पहले कॉल पर आलसी सेट कर सकते हैं। ईजी।

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 ...  
    } 

} 
+0

यह मेरे लिए काम करता चाहते हो सकता है ट्यूटोरियल समझा है कि अपने ढांचे को कॉन्फ़िगर कैसे करें के बहुत सारे है। बहुत बहुत धन्यवाद! –

7

यह एक पुराना सवाल है, लेकिन मैं उन लोगों के लिए अपना उत्तर जोड़ूंगा जो मुझे इस मुद्दे पर Google पसंद करते हैं।

आप GenericFilterBean से अपनी फ़िल्टर वारिस चाहिए और एक स्प्रिंग @Component

@Component 
public class MyFilter extends GenericFilterBean { 

    @Autowired 
    private MyComponent myComponent; 

//implementation 

} 

के रूप में चिह्नित और फिर वसंत संदर्भ में इसे पंजीकृत:

@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; 
    } 
} 

यह ठीक से फिल्टर में अपने घटकों autowires।

+2

आपने अभी इसे दबाया। धन्यवाद – Gandhi

2

अपने फिल्टर वर्ग फैली तो 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"); 
}