2014-05-22 31 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) 
       ... 
    } 
} 
相关问题