来自数据库的 Spring Boot 安全 REST 基本身份验证

She*_*i7y 9 java spring spring-security spring-boot spring-rest

我有一个问题,当我使用带有inMemoryAuthentication 的基本身份验证时,如下面的代码片段所示,它工作得很好。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user1").password("secret1").roles("USER")
                .and()
                .withUser("admin").password("123456").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().antMatchers("/**").hasRole("ADMIN").and()
                .csrf().disable().headers().frameOptions().disable();
    }

}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用 get database 来获取将用于身份验证的用户数据时,它不起作用,只会发回 403 响应。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;//MySQL db via JPA

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
        auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery("select username, password, 1 as enabled from user where username=?")
                .authoritiesByUsernameQuery("select username, role from user where username=?");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().antMatchers("/**").hasRole("ADMIN").and()
                .csrf().disable().headers().frameOptions().disable();

    }

}
Run Code Online (Sandbox Code Playgroud)

现在,这只是 Spring-Boot REST 应用程序的情况,我在 Spring MVC 应用程序和 /login 页面中尝试了相同的方法,并且它与inMemoryAuthentication和jdbcAuthentication一起使用。

Mis*_*s94 7

我遇到了同样的问题,就我而言,以下解决方案非常有效

创建一个实现AuthenticationProvider接口的类:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserService userService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String email = authentication.getName();
        String password = authentication.getCredentials().toString();

        User user = userService.findUserByEmail(email);

        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(user.getRole().getDescription())); // description is a string

        return new UsernamePasswordAuthenticationToken(email, password, authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里对用户进行身份验证,您使用您的用户服务通过电子邮件(用户名)从数据库中检索用户,并使用他的电子邮件、密码及其授予的权限(例如:USER、ADMIN)创建令牌

然后在您的SecurityConfig课程中使用您刚刚创建的 bean,如下所示:

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider authProvider;

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().antMatchers("/**").hasRole("ADMIN").and()
                .csrf().disable().headers().frameOptions().disable();
    }
}
Run Code Online (Sandbox Code Playgroud)