2014-05-22 46 views
1

在用戶身份驗證我需要檢索他的遠程地址和遠程主機。
我想實現一個自定義過濾器來支持這個,但我得到「authenticationManager必須指定」。
另一個疑問是...以編程方式註冊自定義過濾器的正確方法是什麼?如何在Spring Security中以編程方式配置自定義過濾器?

使用配置註釋:

@Configuration 
@EnableWebSecurity 
public class SecurityApplicationConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private SCAAuthenticationFilter scaAuthenticationFilter; 

    @Autowired 
    private SCAAuthenticationProvider scaAuthenticationProvider; 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    auth.authenticationProvider(scaAuthenticationProvider); 
    } 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
    web.ignoring().antMatchers("/resources/**"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http 
     .addFilter(scaAuthenticationFilter) // What is the right way ? 
     .addFilterBefore(scaAuthenticationFilter, AbstractAuthenticationProcessingFilter.class) // What is the right way ? 
     .csrf().disable() 
     .authorizeRequests() 
     .antMatchers("/manual/**").authenticated() 
     .and() 
     .formLogin() 
     .loginPage("/login") 
     .loginProcessingUrl("/login") 
     .failureUrl("/login?error=true") 
     .defaultSuccessUrl("/manual") 
     .permitAll() 
     .and() 
     .logout() 
     .logoutUrl("/logout") 
     .logoutSuccessUrl("/login") 
     .permitAll() 
     .and(); 
    } 
} 

的自定義過濾器:

@Component 
public class SCAAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 
    if (!request.getMethod().equals("POST")) { 
     throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); 
    } 
    String username = obtainUsername(request); 
    String password = obtainPassword(request); 
    String remoteHost = request.getRemoteHost(); 
    String remoteAddr = request.getRemoteAddr(); 
    if (username == null) { 
     username = ""; 
    } 
    if (password == null) { 
     password = ""; 
    } 
    username = username.trim(); 
    SCAAuthenticationToken scaAuthenticationToken = new SCAAuthenticationToken(username, password, remoteHost, remoteAddr); 
    setDetails(request, scaAuthenticationToken); 
    return getAuthenticationManager().authenticate(scaAuthenticationToken); 
    } 

} 
+0

的'addFilter'和'addFilterBefore'行爲應該很清楚從[Javadoc中(HTTP://docs.spring。 IO /彈簧安全/網站/文檔/ 3.2.4.RELEASE/apidocs /組織/ springframework的/安全/配置/註解/網絡/ HttpSecurityBuilder.html)。 –

+0

是的,過濾器被調用,但它發生「必須指定authenticationManager」。我不知道如何設置身份驗證管理器。我嘗試使用@Autowired認證管理器,但不起作用。 –

回答

2

您的自定義過濾器擴展Spring Security的UsernamePasswordAuthenticationFilter,這意味着它需要向認證管理的參考。我將在安全配置中將您的過濾器創建爲@Bean,然後按照this answer的說明解釋用於獲取對AuthenticationManager的引用的不同選項。

+0

你可以在這裏發表一個例子嗎? –

+0

我設法添加了一個authenticationmanager實例的過濾器,但是在登錄時,UsernamePasswordAuthenticationFilter也被使用並且它正在調用空指針。 –

1

在被延長WebSecurityConfigurerAdapter類,覆蓋authenticationManagerBean()方法,並與@Bean註釋它是這樣:

@Configuration 
@EnableWebMvcSecurity 
public class YourCustomConfig extends WebSecurityConfigurerAdapter{ 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

現在,您將能夠@Autowire的AuthenticationManager會在其他班級。

3

您需要設置一個authenticationManagerBean您的擴展過濾器和配置它科爾

@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    @Bean 
    public ExUsernamePasswordAuthenticationFilter exUsernamePasswordAuthenticationFilter() 
      throws Exception { 
     ExUsernamePasswordAuthenticationFilter exUsernamePasswordAuthenticationFilter = new ExUsernamePasswordAuthenticationFilter(); 
     exUsernamePasswordAuthenticationFilter 
       .setAuthenticationManager(authenticationManagerBean()); 
     return exUsernamePasswordAuthenticationFilter; 
    } 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     RequestMatcher requestMatcher = new RequestMatcher() { 
      @Override 
      public boolean matches(HttpServletRequest httpServletRequest) { 
       if (httpServletRequest.getRequestURI().indexOf("/api", 0) >= 0) { 
        return true; 
       } 
       return false; 
      } 
     }; 

     http 
       .addFilterBefore(exUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) 
       ... 
    } 
} 
相關問題