Настройка безопасности http с типом базы данных = Запрещено, статус = 403 - PullRequest
1 голос
/ 26 сентября 2019

Я пытаюсь настроить 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;
    }
}

1 Ответ

1 голос
/ 27 сентября 2019

Проблема в вашем классе CustomUserDetails.Вы создаете SimpleGrantedAuthority с помощью объекта роли, а не имени роли объекта роли.Метод getAuthorities должен выглядеть примерно так:

...
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {

    return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role.getRole())).collect(Collectors.toList());
}
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...