Spring security 未调用Spring安全身份验证筛选器

Spring security 未调用Spring安全身份验证筛选器,spring-security,Spring Security,我正在尝试向SpringHttpSecurity添加自定义筛选器。此筛选器必须检查用户名是否位于外部提供的列表中,并作为集注入筛选器中 无论我把过滤器放在哪里,它的方法attemptAuthentication都不会被调用。以下是过滤器代码: import java.io.IOException; import java.util.Base64; import java.util.Set; import javax.servlet.ServletException; import javax.

我正在尝试向Spring
HttpSecurity
添加自定义筛选器。此筛选器必须检查用户名是否位于外部提供的列表中,并作为
集注入筛选器中

无论我把过滤器放在哪里,它的方法
attemptAuthentication
都不会被调用。以下是过滤器代码:

import java.io.IOException;
import java.util.Base64;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

public class MyRoleFilter extends AbstractAuthenticationProcessingFilter {

    final Set<String> authorisedUsers;

    public WhoRoleFilter(String url, AuthenticationManager authenticationManager, Set<String> authorisedUsers) {
        super(new AntPathRequestMatcher(url));
        this.authorisedUsers= authorisedUsers;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException, IOException, ServletException {
        // In BASIC authentication user:password come as Base64 in the Authorization header
        final String authorization = request.getHeader("Authorization");
        final String[] userPasswd = new String(Base64.getDecoder().decode(authorization)).split(":");
        // The docs of AbstractAuthenticationProcessingFilter says it must throw an exception in case authentication fails
        // https://docs.spring.io/spring-security/site/docs/4.2.6.RELEASE/apidocs/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html#attemptAuthentication-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-
        if (userPasswd.length!=2)
                throw new BadCredentialsException("Bad Credentials");
        if (authorisedUsers.contains(userPasswd[0])) {
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(userPasswd[0], userPasswd[1]);
            return this.getAuthenticationManager().authenticate(authRequest);
        } else {
            throw new BadCredentialsException("User has not the correct role");
        }
    }

}
我不确定在构建链期间,
addFilterBefore()
。此外,用户名列表过滤器还需要针对LDAP服务器的标准用户+密码。LDAP身份验证已就位并处于工作状态

更新,这是位于
SecurityConfig的
配置全局(AuthenticationManagerBuilder)

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
    try {
        auth.ldapAuthentication()
            .userDnPatterns(ConfigurationProvider.get().getProperty(Property.PROP_LDAP_USER_BASE_DN))
            .contextSource(contextSource())
            .passwordCompare()
            .passwordAttribute(ConfigurationProvider.get().getProperty(Property.PROP_LDAP_PASSWORD_ATTRIBUTE));
    } catch (Exception exc) {
        LOG.error(exc.getMessage(), exc);
    }
}

在研究之后回答我自己的问题。这就是我如何实现
SecurityConfig
和我的身份验证处理过滤器,以便在使用LDAP存储用户凭据的基本身份验证中添加自定义角色检查

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private String Set<String> myUsers;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        myUsers = new HashSet<>(Arrays.asList("John","James","Jeremy"));
        try {
            auth.ldapAuthentication()
                    .userDnPatterns("ldap.user.base.dn")
                    .contextSource(contextSource())
                    .passwordCompare()
                    .passwordAttribute("ldap.password.attribute");
            auth.authenticationEventPublisher(defaultAuthenticationEventPublisher());
        } catch (Exception exc) {
            // LOG.error(exc.getMessage(), exc);
        }
    }

    @Override
    @Autowired
    public void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) {
        super.setAuthenticationConfiguration(authenticationConfiguration);
    }

    @Override
    @Autowired
    public void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
        super.setObjectPostProcessor(objectPostProcessor);
    }

    @Override
    protected void configure(HttpSecurity http) {
        try {
            http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/disabled")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .addFilterAfter(new MyFilter("/services/my/path",  this.authenticationManager(), myUsers), BasicAuthenticationFilter.class)
            .httpBasic();

            http.logout().deleteCookies("JSESSIONID")
            .clearAuthentication(true)
            .invalidateHttpSession(true);
        } catch (Exception exc) {
            // LOG.error(exc.getMessage(), exc);
        }
    }
}
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private String Set<String> myUsers;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        myUsers = new HashSet<>(Arrays.asList("John","James","Jeremy"));
        try {
            auth.ldapAuthentication()
                    .userDnPatterns("ldap.user.base.dn")
                    .contextSource(contextSource())
                    .passwordCompare()
                    .passwordAttribute("ldap.password.attribute");
            auth.authenticationEventPublisher(defaultAuthenticationEventPublisher());
        } catch (Exception exc) {
            // LOG.error(exc.getMessage(), exc);
        }
    }

    @Override
    @Autowired
    public void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) {
        super.setAuthenticationConfiguration(authenticationConfiguration);
    }

    @Override
    @Autowired
    public void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
        super.setObjectPostProcessor(objectPostProcessor);
    }

    @Override
    protected void configure(HttpSecurity http) {
        try {
            http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/disabled")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .addFilterAfter(new MyFilter("/services/my/path",  this.authenticationManager(), myUsers), BasicAuthenticationFilter.class)
            .httpBasic();

            http.logout().deleteCookies("JSESSIONID")
            .clearAuthentication(true)
            .invalidateHttpSession(true);
        } catch (Exception exc) {
            // LOG.error(exc.getMessage(), exc);
        }
    }
}
public class MyFilter extends AbstractAuthenticationProcessingFilter {

    final Set<String> authorisedUsers;

    public MyFilter(String url, AuthenticationManager authenticationManager, Set<String> authorisedUsers) {
        super(new AntPathRequestMatcher(url));
        this.authorisedUsers = authorisedUsers;
        this.setAuthenticationManager(authenticationManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException, IOException, ServletException {
        // In BASIC authentication user:password come as Base64 in the Authorization header
        final String authorization = request.getHeader("Authorization");
        String authorizationBasic = authorization; 
        if (authorization.startsWith("Basic")) {
            authorizationBasic = authorization.split(" ")[1];
        }
        final String[] userPasswd = new String(Base64.getDecoder().decode(authorizationBasic)).split(":");
        // The docs of AbstractAuthenticationProcessingFilter says it must throw an exception in case authentication fails
        // https://docs.spring.io/spring-security/site/docs/4.2.6.RELEASE/apidocs/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html#attemptAuthentication-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-
        if (userPasswd==null || userPasswd.length!=2)
            throw new BadCredentialsException("Bad Credentials");
        if (authorisedUsers.contains(userPasswd[0])) {
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(userPasswd[0], userPasswd[1]);
            return getAuthenticationManager().authenticate(authRequest);
        } else {
            throw new BadCredentialsException("User " + userPasswd[0] + " has not the WHO role");
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {

        SecurityContextHolder.getContext().setAuthentication(authResult);

        chain.doFilter(request, response);
    }
}