spring-mvc - Spring 安全问题:编码密码看起来不像 BCrypt
问题描述
我正在使用 Spring Boot 和 Spring Security 对我的应用程序进行身份验证,但是当我尝试登录时出现此错误。
Hibernate: select users0_.id_user as id_user1_5_, users0_.email as email2_5_, users0_.first_name as first_na3_5_, users0_.last_name as last_nam4_5_, users0_.password as password5_5_, users0_.rol as rol6_5_ from users users0_ where users0_.email=?
Hibernate: select employee0_.id_employee as id_emplo1_1_0_, employee0_.hire_date as hire_dat2_1_0_, users1_.id_user as id_user1_5_1_, users1_.email as email2_5_1_, users1_.first_name as first_na3_5_1_, users1_.last_name as last_nam4_5_1_, users1_.password as password5_5_1_, users1_.rol as rol6_5_1_ from employee employee0_ left outer join users users1_ on employee0_.id_employee=users1_.id_user where employee0_.id_employee=?
2020-02-03 13:00:47.222 WARN 66020 --- [nio-8080-exec-9] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
我的代码是:
这是我拥有与安全相关的功能的课程。
安全配置.java
package com.sample.util;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
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.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.sample.negocio.services.UserService;
/**
* Manages project security
* @author csar
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//Desde donde consultamos a la base de datos
@Autowired
DataSource dataSource;
@Autowired
UserService userDetailsService;
@Autowired
private BCryptPasswordEncoder bcrypt;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and().formLogin()
.loginPage("/app/login").permitAll()
.failureUrl("/app/login?error=true")
.defaultSuccessUrl("/app/home");
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
/*PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
builder.inMemoryAuthentication()
.withUser("pepe@gmail.com")
.password(encoder.encode("1234"))
.roles("USER");*/
builder.userDetailsService(userDetailsService).passwordEncoder(bcrypt);
/* builder
.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select email as username, password as password, rol as enabled from users WHERE id_user=?")
.authoritiesByUsernameQuery("SELECT ? as username, 'USER' as ROLE")
.passwordEncoder(new BCryptPasswordEncoder());*/
}
@Override
public void configure(WebSecurity security) {
security.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");
}
}
这是我拥有服务和所有功能的课程。
用户服务.java
package com.sample.negocio.services;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.core.userdetails.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sample.modelo.Users;
import com.sample.negocio.repository.UserRepository;
/**
* Clase para definir los servicios de User
* @author vcanizar
*
*/
@Service
@Transactional(readOnly=true)
public class UserService implements UserDetailsService{
@Autowired
private final UserRepository userRepository;
//Metodo que asigna el repositorio UserRepository en el servicio UserService
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
/**
* Servicio que devuelve una lista de Usuarios
* @return
*/
public List<Users> findAll(){
return this.userRepository.findAll();
}
/**
* Método para realizar la operación de guardar un User
* @param user
* @return
*/
public Users create(Users user) {
return this.userRepository.save(user);
}
/**
* Método para realizar la operación de actualizar un User
* @param user
* @return
*/
@Transactional
public Users update(Users user) {
return this.userRepository.save(user);
}
/**
* Método para realizar la operación de borrar un Employee
* @param user
*/
@Transactional
public void delete(Users user) {
this.userRepository.delete(user);
}
@Transactional
public Users findByIdUser(String idUser) {
return this.userRepository.findByIdUser(idUser);
}
/**
* Método para consultar un user por su email
* @param iduser
* @return
*/
@Override
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException {
Users user= userRepository.findByEmail(email);
//Creamos un arraylist a partir de una lista de roles que vamos a introducir en los detalles de usuario
List<GrantedAuthority> listaRoles = new ArrayList<>();
listaRoles.add(new SimpleGrantedAuthority("ROLE_" + userRepository));
//Creamos un UserDetails a partir de los datos recopilados del usuario
UserDetails userDet = new User(user.getEmail(),user.getPassword(),listaRoles);
return userDet;
}
}
我拥有用户类存储库的类
用户存储库
package com.sample.negocio.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.sample.modelo.Users;
/**
* Interfaz para definir las operaciones de bbdd relacionadas con User
* @author vcanizar
*
*/
public interface UserRepository extends JpaRepository<Users, String>{
/**
* Definición de método para buscar los Users por su ID
* @param idUser
* @return
*/
public Users findByIdUser(String idUser);
public Users findByEmail(String email);
}
控制器
用户控制器
/**
*
*/
package com.sample.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sample.modelo.Users;
import com.sample.negocio.services.UserService;
/**
* @author vcanizar
*
*/
@RestController
@CrossOrigin(origins = "http://localhost:4200")
@RequestMapping("/postgresApp")
public class UserController {
@Resource
UserService userService;
@GetMapping(value = "/userList")
public List<Users> getUsers() {
return userService.findAll();
}
@PostMapping(value = "/createUser")
public void createUser(@RequestBody Users user) {
userService.create(user);
}
@PutMapping(value = "/updateUser")
public void updateUser(@RequestBody Users user) {
userService.update(user);
}
@DeleteMapping(value = "/deleteUserById")
public void deleteUser(@RequestBody Users user) {
userService.delete(user);
}
}
用户类和实体
用户.java
package com.sample.modelo;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* Clase que representa la tabla Employee
*
* @author vcanizar
* @Id: Generamos el ID
* @OnetoOne: generamos un Primary key compartido entre la tabla Employee y
* User(Teniendo User el Id principal)
*
*/
@Data
@Entity
@Table(name = "users")
public class Users {
// iduser
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
private String idUser;
// Relacion con employee
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Employee employee;
private String firstName;
private String lastName;
private String email;
private String password;
private String rol;
/*@AllArgsConstructor
public enum language {
FRENCH("FRENCH"), ENGLISH("ENGLISH"), SPANISH("SPANISH");
private String language;
}*/
public Users() {
}
}
解决方案
确保您的客户端密码已编码。
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(clientId)
.secret(passwordEncoder.encode(clientSecret))
.authorizedGrantTypes(grantType)
.scopes(scopeRead, scopeWrite)
.resourceIds(resourceIds);
}
推荐阅读
- gradle - 如何访问 Plugin Java 源代码中的 gradle.ext 属性?
- ruby - Rails TypeError:没有将符号隐式转换为整数
- javascript - 让 php 在 ajax 调用之后运行,而不是之前
- dataframe - Palantir 代工厂使用导入的数据集使用 pyspark 执行 nlp 操作
- cytoscape.js - Dynamically add a css class to cytoscape node on the tap of the node using cytoscape.js
- reactjs - Gatsby React app 报错 Refresh Babel transform 只能在开发环境中启用
- gekko - Gekko 中每个列求解器输出的含义
- python - Django - 使用过滤器查询时传递结果列表
- c# - 将 service worker 添加到 startup.cs 文件
- javascript - 链接打开选项卡时如何留在当前选项卡上?Javascript