SpringSecurity configure () метод Проблемы с конфигурацией - PullRequest
0 голосов
/ 11 ноября 2018

Я разработал REST API, где методы защищены с помощью SpringSecurity.

GITHUB LINK -> Проект

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

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();
    }

}

AdminController
----------------------

@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 для ADMIN , но мне не хватает аутентификации на URL для USER

Аналогичным образом, если я комментирую admin / , тогда можно получить доступ к части USER . Он ведет себя как Ordering, который когда-либо находится в первом URL, он признает это, а второй просто дает 403 в браузере, а не что-либо в консоли.

Это что-то вроде «Ордена», к которому первому можно получить доступ

Есть ли где-нибудь, что я делаю не так.

Если я не буду комментировать @EnableGlobalSecurity, @PreAuthorize, я не смогу получить доступ ни к одному из URL , которые предназначены для ADMIN и USER просто 403, поэтому я не могу пропустить @EnableGlobalSecurity, @PreAuthorize, поскольку они предназначены для защиты методов REST API

1 Ответ

0 голосов
/ 11 ноября 2018

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

http
            /*.authorizeRequests()
            .antMatchers("/user/**")
            .authenticated()
            .anyRequest()
            .hasRole("USER")
            .and()*/
            .authorizeRequests()
            .antMatchers("/admin/**")
            .hasRole("ADMIN")
            .antMatchers("/user/**")
            .hasAnyRole("ADMIN", "USER")
            .and()
            .formLogin()
            .permitAll();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...