Spring 安全基本身份验证未使用 CustomUserDetailsS​​ervice

Spring Security Basic Auth not using CustomUserDetailsService

我的项目是最新的 Spring Boot + Jersey,我在登录验证方面遇到问题。

我的安全配置是:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
@Autowired
private DataSource datasource;

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http.csrf().disable().authorizeRequests()
            .antMatchers("/api/user/**").permitAll()
            .antMatchers("/api/**").authenticated().and().httpBasic();

}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
    auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
    auth.jdbcAuthentication().dataSource(datasource);
}

@Bean
public UserDetailsService userDetailsService()
{
    return new CustomUserDetailsService(datasource);
}
}

但是当我这样做时:

@POST
@Path("authenticate")
@Produces(MediaType.APPLICATION_JSON)
public Response authenticate(@HeaderParam("username") String username, @HeaderParam("password") String password)
{
    UsernamePasswordAuthenticationToken authenticationToken =
            new UsernamePasswordAuthenticationToken(username, password);
    Authentication authentication = this.authManager.authenticate(authenticationToken);
    SecurityContextHolder.getContext().setAuthentication(authentication);

    UserDetails userDetails = this.userService.loadUserByUsername(username);

    return createOkResponse(userDetails.getUsername());
}

身份验证方法在 InMemoryUserDetailsManager 内部使用,而不是我需要用于登录验证的 CustomUserDetailsS​​ervice。 我该如何更改?

如果需要:

public class CustomUserDetailsService extends JdbcUserDetailsManager implements UserDetailsService
{
@Autowired
private UserRepository userRepository;

public CustomUserDetailsService(DataSource datasource)
{
    setDataSource(datasource);
}

@Override
public CurrentUserInfo loadUserByUsername(String email)
        throws UsernameNotFoundException
{

    User user = userRepository.findByPrimaryEmailAndEnabledTrue(email);
    handleUserNotFound(email, user);

    return new CurrentUserInfo(user);
}

private void handleUserNotFound(String email, User user)
{
    if (user == null)
    {
        throw new UsernameNotFoundException("No user found with email: " + email);
    }
}
}

入门依赖项:

compile("org.springframework.boot:spring-boot-starter-web") {
    exclude module: 'spring-boot-starter-tomcat'
}
compile "org.springframework.boot:spring-boot-starter-jetty"
compile "org.springframework.boot:spring-boot-starter-security"
compile "org.springframework.boot:spring-boot-starter-aop"
compile "org.springframework.boot:spring-boot-starter-data-jpa"
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
compile "org.springframework.boot:spring-boot-starter-jersey"
compile("org.springframework.boot:spring-boot-starter-actuator") { exclude module: 'hsqldb' }

问题是您 "registering" 是一个 AuthenticationManager 仅可用于 /api URI,它不会作为 bean 暴露给 ApplicationContext。当使用 Spring Boot 时,将添加一个全局的,并在其中注入一个带有生成密码的默认用户。

Spring 引导自动配置将检测是否存在已经可用的 AuthenticationManager。要注册一个全局的,只需创建一个方法,该方法将 AuthenticationManagerBuilder 作为参数并在 @Autowired 中进行注释。只要确保它没有被命名为 configure,因为那样是行不通的。

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
    auth.jdbcAuthentication().dataSource(datasource);
}