使用bcrypt进行Spring身份验证

时间:2014-11-15 22:32:41

标签: java spring spring-security

我试图将bcrypt添加到我的弹簧应用程序中。验证工作正常没有。但是当我尝试使用bcrypt进行编码时,我得到了" Reason:Bad credentials"在尝试登录时。

我的用户模型如下所示。

@Entity
@Table(name="users") // user is a reserved word in postgresql
public class User extends BaseEntity {
    private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    ...
    @Column(nullable=false)
    private String password;

    ...

    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        String hashedPassword = passwordEncoder.encode(password);
        this.password = hashedPassword;
    }

    ...
}

My SecurityConfig如下所示。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    private BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
...
}

以上看似乎是对的吗?我需要做的比我已经完成的更多吗?

2 个答案:

答案 0 :(得分:2)

我没有发布足够的代码。当然,我的用户模型并没有说明整个故事。我还有一个名为SecurityUser的课程,我在下面发帖。由于复制构造函数,密码被哈希两次。

public class SecurityUser extends User implements UserDetails {

    private static final long serialVersionUID = 867280338717707274L;

    public SecurityUser(User user) {
        if(user != null)
        {
            this.setId(user.getId());
            this.setName(user.getName());
            this.setEmail(user.getEmail());
            this.setPassword(user.getPassword());
            this.setRoles(user.getRoles());
        }
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        Set<Role> userRoles = this.getRoles();

        if(userRoles != null)
        {
            for (Role role : userRoles) {
                SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.getName());
                authorities.add(authority);
            }
        }
        return authorities;
    }

...
}

我已将passwordEncoder方法公开并将其提升为bean,因此我可以将其自动装入我的UserService,如下所示。这样,如果我决定这样做,我只需要在一个地方更改编码器。

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;


    public User create(User user) {
        String hashedPassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(hashedPassword);
        return userRepository.save(user);
    }
...
}

答案 1 :(得分:1)

以下是我如何设置它。

用户表有4个属性(以及其他)

  1. id(自动增量)
  2. 用户名(或email_address)字段
  3. 密码字段。
  4. 已启用(值将为1或0)
  5. 角色表(3个属性)

    1. id(自动增量)
    2. user_id(用户表外键)
    3. 权限;
    4. 为这两个表创建Java实体。

      Spring Security Configuration Class如下所示:

      @Autowired 
      public void  configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
      String usrsByUnameQry = "SELECT u.email_address, u.password, u.enabled FROM user u WHERE u.email_address=?"; 
      3String authByUnameQry = "SELECT u.email_address, r.authority FROM user u, role r WHERE u.id=r.user_id AND u.email_address=?"; 
      
      auth 
      .eraseCredentials(false) 
      .jdbcAuthentication() 
      .dataSource(dataSource) 
      .passwordEncoder(passwordEncoder()) 
      .usersByUsernameQuery(usrsByUnameQry) 
      .authoritiesByUsernameQuery(authByUnameQry); 
          } 
      
       @Override 
        protected void configure(HttpSecurity http) throws Exception { 
            http 
               .formLogin() 
                  .usernameParameter("username") //username property defined in html form
                  .passwordParameter("password") //password property defined in html form
                    // url that holds login form 
                    .loginPage("/signin") 
                    .loginProcessingUrl("/signin/authenticate") 
                    .failureUrl("/loginfail") 
                    // Grant access to users to the login page
                    .permitAll() 
                    .and() 
                .logout() 
                  .logoutUrl("/signout") 
                  .deleteCookies("JSESSIONID") 
                  .logoutSuccessUrl("/signin") 
                  .and() 
                         .authorizeRequests() 
                      .antMatchers("/foo/**").permitAll()//Grant access to all (no auth reuired) 
                      .antMatchers("/").hasAnyAuthority("ROLE_USER","ROLE_ADMIN") //Grant access to only users with role "ROLE_USER" or "ROLE_ADMIN"  
        } 
      
       @Bean(name = "authenticationManager") 
       @Override 
       public AuthenticationManager authenticationManagerBean() throws Exception { 
          return super.authenticationManagerBean(); 
         } 
      
       @Bean   
       public BCryptPasswordEncoder passwordEncoder(){ 
              return new BCryptPasswordEncoder(); 
          } 
      
      @Bean 
      public TextEncryptor textEncryptor(){ 
          return Encryptors.noOpText(); 
      }