#spring-boot #spring-security #jwt
Вопрос:
Вот класс конфигурации, в котором я распределяю доступ в соответствии с ролями:
@Configuration @EnableWebSecurity @AllArgsConstructor //@EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurity extends WebSecurityConfigurerAdapter { private final UserDetailServiceImpl userDetailsService; private final BCryptPasswordEncoder bCryptPasswordEncoder; private static final String[] PUBLIC_URLS = { "/v2/api-docs", "/swagger-resources/**", "/swagger-ui/**", "/webjars/**" }; @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable().authorizeRequests() .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll() .antMatchers(PUBLIC_URLS).permitAll() .antMatchers ("/user/**"). hasAnyRole ("USER", "ADMIN") .antMatchers("/user/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .addFilter(new JWTAuthenticationFilter(authenticationManager())) .addFilter(new JWTAuthorizationFilter(authenticationManager())) /* this disables session creation on Spring Security */ .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder); } @Bean CorsConfigurationSource corsConfigurationSource() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); return source; } }
Это класс контроллера, в котором я хочу использовать роль администратора:
@AllArgsConstructor @Validated @RestController @RequestMapping("/user") @Api( tags = "Users") public class UserController { private final UserService userService; @DeleteMapping("/admin/{id}") @PreAuthorize("hasRole('ADMIN')") public ResponseEntitylt;Voidgt; delete(@PathVariable @Min(1) int id) { userService.delete(id); return ResponseEntity.ok().build(); }
Если вы удалите в конфигурации:
.antMatchers ("/user/**"). hasAnyRole ("USER", "ADMIN") .antMatchers("/user/admin/**").hasRole("ADMIN")
Затем ПОЛЬЗОВАТЕЛЬ также удалит его. Но если вы оставите это совпадение ролей и сделаете запрос от администратора, то при удалении пользователя произойдет ошибка.
{ "timestamp": "2021-12-01T21:30:05.647 00:00", "status": 403, "error": "Forbidden", "message": "", "path": "/user/admin/2" }
Если вы оставите эту аннотацию @enableglobalmethod Security(prePostEnabled = true), то снова повторится та же ошибка, и ничего нельзя будет удалить. Есть ли какие-либо предложения по решению этой проблемы?
Комментарии:
1. Пожалуйста, сформулируйте проблему более четко. Вы пытаетесь получить доступ к пути /пользователю/администратору с ролью ПОЛЬЗОВАТЕЛЯ? Кроме того, какие роли вы хотите точно соответствовать каждой конечной точке?
2. Мне нужен только администратор, чтобы иметь возможность использовать метод контроллера, который я показал. Но с помощью пользователя я просто проверяю: может ли кто-то, кроме администратора, использовать эту конечную точку?