Я пытаюсь настроить SecurityConfig с помощью метода configure (HttpSecurity http).Я использую сущности для пользователя и роль для базы данных.Выглядит хорошо, я могу добавить одного пользователя и одного администратора.
Для его настройки мне пришлось использовать UserDetailsService
, который берет информацию из базы данных.Вроде работает с открытыми страницами, а страницы с авторизацией для всех.Но когда я хочу добавить страницу только для ADMIN, у меня появляется ошибка
type=Forbidden, status=403
.
Я искал ответ в стеке и добавил несколько аннотаций, таких как:
@PreAuthorize("hasAnyRole('ADMIN')")
, но он все еще не работает.Я надеюсь, что это небольшая ошибка, но после нескольких дней работы я не знаю, где искать.Любая помощь высоко ценится.
Это мои классы:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/",
"/resources/**").permitAll().anyRequest().permitAll()
.and()
.authorizeRequests()
.antMatchers("/admin").authenticated().anyRequest().hasAnyRole("ADMIN")
.and()
.formLogin().permitAll();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailsService();
}
}
@RestController
public class SimpleHelloController {
@PreAuthorize("hasAnyRole('ADMIN')")
@GetMapping("/admin")
public String hello(){
return "Hello there admin";
}
}
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long role_id;
private String role;
}
@Entity
@Setter
@Getter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long user_id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
}
@Getter
@Setter
public class CustomUserDetails implements UserDetails {
private User user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.collect(Collectors.toList());
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findUserByUsername(username);
CustomUserDetails customUserDetails = null;
if(user != null){
customUserDetails = new CustomUserDetails();
customUserDetails.setUser(user);
}else{
throw new UsernameNotFoundException("User " + username + " not exist");
}
return customUserDetails;
}
}