Я новичок в весне и весенней безопасности.Я пытался реализовать базовый вход в систему с аутентификацией / авторизацией, используя Spring Security, я следовал нескольким учебникам в Интернете, но ни один из них не помог мне.Когда я пытаюсь войти в систему с пользователем, который находится в моей базе данных, он выдает мне ошибку: неверные учетные данные
Вот коды, которые я использовал: объекты пользователя / роли / разрешения
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
private int id;
private String name;
private String email;
private String password;
private String usual_IP;
private int logged;
@ManyToMany
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private List<Role> roles;
Роль
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "role_id")
private int id;
private String name;
private String description;
@ManyToMany(mappedBy = "roles")
@JsonIgnore
private List<User> users;
Привилегия
@Entity
public class Privilege {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "Privilege_id")
private int id;
private String name;
@ManyToMany(mappedBy = "privileges")
private List<Role> roles;
Вот конфигурация пружины
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private DataSource dataSource;
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests()
.antMatchers("/", "/login", "/logout").permitAll()
.antMatchers("/users").permitAll()
.antMatchers("/user/").permitAll()
.antMatchers("/user/**").permitAll()
.antMatchers("/users/**").permitAll()
.antMatchers("/roles").permitAll()
.antMatchers("/role").permitAll()
.antMatchers("/role/**").permitAll()
.antMatchers("/userInfo").access("hasAnyRole('USER', 'ADMIN')")
.antMatchers("/admin").access("hasRole('ADMIN')")
.anyRequest().authenticated().and().csrf().disable().formLogin()
.and().exceptionHandling().accessDeniedPage("/403")
.and().formLogin()//
.loginProcessingUrl("/j_spring_security_check")
.loginPage("/login")//
.defaultSuccessUrl("/userAccountInfo")//
.failureUrl("/login?error=true")//
.usernameParameter("name")//
.passwordParameter("password")
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/logoutSuccessful")
.and().exceptionHandling();
}
здесь - реализация UsersDetailsService
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User user = userRepository.findByName(name);
if(user==null) {throw new UsernameNotFoundException("No such user: " + name);
} else if (user.getRoles().isEmpty()) {
throw new UsernameNotFoundException("User " + name + " has no authorities");
}
UserDetailsAdapter userToAdapt = new UserDetailsAdapter(user);
return userToAdapt;
}
}
Пользователь детализации
public class UserDetailsAdapter implements UserDetails {
private User user;
public UserDetailsAdapter(User user) {this.user = user;}
public User getAccount() {return user;}
public Integer getId(){return user.getId();}
public String getEmail () {return user.getEmail();}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities= new ArrayList<>();
for (Role role: user.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
role.getPrivileges().stream().map(p -> new SimpleGrantedAuthority(p.getName())).forEach(authorities::add);
}
return authorities;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getName();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Контроллер входа в систему
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage(Model model) {
return "loginPage";
}
@RequestMapping(value = "/userInfo", method = RequestMethod.GET)
public String userInfo(Model model, User user) {
// After user login successfully.
String userName = user.getName();
System.out.println("User Name: " + userName);
User loginedUser = user;
String userInfo = user.toString();
model.addAttribute("userInfo", userInfo);
return "userInfoPage";
}
И шаблон из тимьяна
<!-- /login?error=true -->
<div th:if="${#request.getParameter('error') == 'true'}"
style="color:red;margin:10px 0px;">
Login Failed!!!<br />
Reason :
<span th:if="${#session!= null and
#session.getAttribute('SPRING_SECURITY_LAST_EXCEPTION') != null}"
th:utext="${#session.getAttribute
('SPRING_SECURITY_LAST_EXCEPTION').message}">
Static summary
</span>
</div>
<h3>Enter user name and password:</h3>
<form name='f' th:action="@{/j_spring_security_check}" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='name' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td>Remember Me?</td>
<td><input type="checkbox" name="remember-me" /></td>
</tr>
<tr>
<td><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
</form>
РЕДАКТИРОВАТЬ
Вот служба, которая сохраняет пользователя в БД и кодирует пароль
@Override
public void saveUser(User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
userRepository.save(user);
}
А вот контроллер, который я использовал для ручного добавления нового пользователя в БД через почтальона
@RequestMapping(value = "/users", method = RequestMethod.POST)
public ResponseEntity<Void> createUser(@RequestBody User user, UriComponentsBuilder ucBuilder) {
if (userServices.isUserExist(user)) {
return new ResponseEntity(new CustomErrorType("Unable to create. A User with name " +
user.getName() + " already exist."),HttpStatus.CONFLICT);
}
userServices.saveUser(user);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/api/user/{id}").buildAndExpand(user.getId()).toUri());
return new ResponseEntity<>(headers, HttpStatus.CREATED);
}
Кто-то может помочь, я не могу точно определить ошибку, большое спасибо