带有密码编码器的spring boot jdbc auth

时间:2018-07-16 08:28:21

标签: java spring-boot authentication

我想在我的网站上创建身份验证,并且创建了看起来如下的SecurityConfiguration类:

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private DataSource dataSource;

    @Value("${spring.queries.users-query}")
    private String usersQuery;

    @Value("${spring.queries.roles-query}")
    private String rolesQuery;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        //auth.inMemoryAuthentication().withUser("user").password("{noop}pass").authorities("ADMIN");

        auth.
        jdbcAuthentication()
            .passwordEncoder(passwordEncoder())
            .usersByUsernameQuery(usersQuery)
            .authoritiesByUsernameQuery(rolesQuery)
            .dataSource(dataSource);    
    }

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

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/login").permitAll()
                .antMatchers("/managament").hasAuthority("ADMIN")
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/management")
                .usernameParameter("username")
                .passwordParameter("password")
            .and()
                .logout().permitAll();
        http.csrf().disable();

    }

}

在我的resources/application.properties中,我有两个查询

spring.queries.users-query=select username, password, active from user where username=?
spring.queries.roles-query=select u.username, r.role from user u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.username=?

下面也是我的实体

角色

@Entity
@Getter
@NoArgsConstructor
public class Role {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int roleId;

    @Setter
    private String role;    

    public Role(String role) {
        this.role = role;
    }

}

用户

@Entity
@Getter
@NoArgsConstructor
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int userId;

    @Setter
    private String password;

    @Setter
    private String username;

    @Setter
    private int active;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    @Setter
    private Set<Role> roles;

    public User(String password, String username, int active, Set<Role> roles) {
        super();
        this.password = password;
        this.username = username;
        this.active = active;
        this.roles = roles;
    }
}

在SQL数据库中,我还有一个包含user_id和role_id的表,因为它之间存在许多关系。

我的存储库扩展了JpaRepository

当我在内存身份验证中使用时,一切都正常,因此我认为HttpSecurity和WebSecurity配置正确。问题是当我使用

auth.
        jdbcAuthentication()
            .passwordEncoder(passwordEncoder())
            .usersByUsernameQuery(usersQuery)
            .authoritiesByUsernameQuery(rolesQuery)
            .dataSource(dataSource);    

它使我o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt丢了。

有人说由于BCryptPasswordEncoder,数据库中的密码字段应该大于60个字符,但是我有更多的字符,有人告诉其他配置。

我使用了this示例,但这个人没有人们正在谈论的配置。我只是剪切了一些不有用的代码部分,并根据需要对其进行了调整。但是我缺少了一些东西,我也不知道。

1 个答案:

答案 0 :(得分:0)

问题是我的数据库中有密码,例如$2y$12$HCch5QVPslL4UjtZRuCqiuhYybBeBujdyMj.oyH1BTSA6zJFJlZ2C

因为我用https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/APIGateway.html bcrypt生成器生成了它。默认情况下, BCryptPasswordEncoder.class 中的bcrypt强度为 10 。如您所见,开头有$ 2y $ 12 $,而这12就是强度,所以当我尝试编码密码时,由于开头是,它看起来不像bcrypt $ 2y $ 12 $ ,对于此配置,应为 $ 2y $ 10 $

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

如果要将强度更改为12,则应这样做

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(12);
}