SpringSecurity метод configure () Проблемы конфигурации

Я разработал REST api, в котором методы защищены SpringSecurity.

ССЫЛКА НА GITHUB-> Проект

Он работает, но не так, как ожидалось

SpringSecurity.config
---------------------------

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private UserDetailsService userDetailService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailService).passwordEncoder(encode());


    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {


        http
            .csrf().disable();
        http

            .authorizeRequests()
            .antMatchers("/user/**")
            .authenticated()
            .anyRequest()
            .hasAnyRole("USER","ADMIN")
            .and()
            .authorizeRequests()
            .antMatchers("/admin/**")
            .authenticated()
            .anyRequest()
            .hasRole("ADMIN")
            .and()
            .formLogin()
            .permitAll();

        /*http
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER","ADMIN")
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .permitAll();*/

    }

    @Bean
    public BCryptPasswordEncoder encode() {
        return new BCryptPasswordEncoder();
    }

}

Админконтроллер
----------------------

@RestController
@RequestMapping("/admin")
public class AdminController {

    @Autowired
    private UserRepo userRepo;
    @Autowired
    private BCryptPasswordEncoder encoder;

    @PostMapping("/add")
    @PreAuthorize("hasRole('ADMIN')")
    public String addUser(@RequestBody User user) {
        String encodedPwd= encoder.encode(user.getPassword());
        user.setPassword(encodedPwd);
        userRepo.save(user);
        return "user added sucessfully...";
    }

    @GetMapping("/demo")
    @PreAuthorize("hasRole('ADMIN')")
    public String getDemo() {
        return "Hi";
    }

}

CustomController
-------------------------

@RestController
@RequestMapping("/user")
public class CustomController {

    @GetMapping("/access")
    @PreAuthorize("hasAnyRole('USER','ADMIN')")
    public String showUser() {

        return "Url Security Provided";
    }
}

CustomUserDetailService
-----------------------------

@Service
public class CustomUserDetailService implements UserDetailsService {

    @Autowired
    private UserRepo userRepo;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user= userRepo.findByUsername(username);
        CustomUserDetails userDetails= null;

        if (user!= null) {
            userDetails= new CustomUserDetails();
            userDetails.setUser(user);
        }else {
            throw new UsernameNotFoundException("User Not Found");
        }
        return userDetails;
    }

}

CustomUserDetail
-----------------

@Getter
@Setter
public class CustomUserDetails implements UserDetails {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private User user;


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

        /*return user.getRoles().stream()
            .map(role->new SimpleGrantedAuthority("ROLE_"+ role))
            .collect(Collectors.toList());*/
        return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
        .collect(Collectors.toList());
    }

    @Override
    public String getPassword() {
        // TODO Auto-generated method stub
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return user.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return true;
    }

    public CustomUserDetails() {
        super();
        // TODO Auto-generated constructor stub
    }

}

Пользователь
----------

@Entity
@Getter
@Setter
@NoArgsConstructor
public class User {

    @Id
    @GenericGenerator(name = "gen",strategy = "increment")
    @GeneratedValue(generator = "gen")
    private int user_id;
    private String username;
    private String password;
    private String email;
    @OneToMany(cascade= CascadeType.ALL, fetch= FetchType.EAGER)
    @JoinTable(name = "user_roles",
                    joinColumns= @JoinColumn(referencedColumnName= "user_id"), 
                    inverseJoinColumns= @JoinColumn(referencedColumnName = "role_id"))
    private Set<Roles> roles;

}

Проблема в: С помощью вышеуказанной настройки я могу получить доступ к URL-адресу, который предназначен для ПОЛЬЗОВАТЕЛЯ, а не для ADMIN

Если я комментирую

http
            /*.authorizeRequests()
            .antMatchers("/user/**")
            .authenticated()
            .anyRequest()
            .hasRole("USER")
            .and()*/
            .authorizeRequests()
            .antMatchers("/admin/**")
            .authenticated()
            .anyRequest()
            .hasRole("ADMIN")
            .and()
            .formLogin()
            .permitAll();

Затем я могу получить доступ к URL, которые предназначены для АДМИНИСТРАТОР, но мне не хватает аутентификации на URL, которые предназначены для ПОЛЬЗОВАТЕЛЬ

Точно так же, если я комментирую админ /, тогда можно будет получить доступ к части ПОЛЬЗОВАТЕЛЬ. Он ведет себя как упорядочивание, который когда-либо находится в первом URL-адресе, он распознает это, а второй просто выдает 403 в браузере, а не в консоли.

Это что-то вроде Порядка, который первым доступен

Я где-нибудь делаю что-то не так?

Если я не буду комментировать @EnableGlobalSecurity, @PreAuthorize, я не могу получить доступ ни к одному из URL, которые предназначены для АДМИНИСТРАТОР и ПОЛЬЗОВАТЕЛЬ, просто 403, поэтому я не могу пропустить @EnableGlobalSecurity, @PreAuthorize, поскольку они предназначены для защиты методов REST API

изменение его на .antMatchers("/admin/**").hasAnyRole("ADMIN") .antMatchers("/user/**").hasAnyRole("USER") должно помочь. Вам не нужно звонить authorizeRequests несколько раз

greengreyblue 11.11.2018 18:45

Я уже пробовал это, в этом случае я не могу получить доступ к URL-адресу на основе ПОЛЬЗОВАТЕЛЯ или URL-адресу на основе ADMIN.

Stone 11.11.2018 18:46

Даже если в консоли БД запросы запускаются, а в браузере просто 403

Stone 11.11.2018 18:51

Это SPRING JPA, поэтому в userRepo у меня есть один метод, который загружает пользователя в соответствии с заданным именем пользователя.

Stone 12.11.2018 09:03

Хотя вы говорите, что sql-запросы выполняются, это означает, что метод выполняется (и вы можете разместить указатель отладки и отладить метод для подтверждения), однако он возвращает 403 означает, что на высоком уровне что-то не так с @Postauthorize, но мы делаем не вижу никаких методов, аннотированных тем же, либо @Preauthorize комментируется в соответствии с вашим опубликованным кодом и, следовательно, не имеет отношения к @EnableGlobalMethodSecurity. можешь поделиться логами?

greengreyblue 12.11.2018 09:23

Как в базе данных выглядит сопоставление пользователя с ролью?

greengreyblue 12.11.2018 09:39

Проверьте сейчас. Я обновил вопрос, включив @EnableGlobalMethodSecurity (securedEnabled = true), @PreAuthorize и т. д.

Stone 12.11.2018 10:33
1
7
35
1

Ответы 1

Просто добавьте разрешение на все свои страницы для вашей роли администратора. Таким образом, вы убедитесь, что ваш администратор может получить доступ к любой странице, которую он хочет.

http
            /*.authorizeRequests()
            .antMatchers("/user/**")
            .authenticated()
            .anyRequest()
            .hasRole("USER")
            .and()*/
            .authorizeRequests()
            .antMatchers("/admin/**")
            .hasRole("ADMIN")
            .antMatchers("/user/**")
            .hasAnyRole("ADMIN", "USER")
            .and()
            .formLogin()
            .permitAll();

Другие вопросы по теме