После нескольких дней борьбы с этим (поиска в СЦ похожих вопросов, проб и ошибок) у меня возникает соблазн отказаться ...
Так что проблема в том, что у меня есть служба REST, основанная наSpring Boot использует Spring Security и JWT для аутентификации.Теперь я хочу защитить некоторые методы, которые будут вызываться только авторизованными людьми, использующими аннотацию @PreAuthorize
.Кажется, это работает отчасти потому, что вместо вызова метода Spring возвращает 404. Я бы ожидал 403.
Я прочитал этот SO-вопрос и попробовал ответы, данные там, но он сделалнет помощи.Я переместил @EnableGlobalMethodSecurity(prePostEnabled = true)
-Annotation из моей SecurityConfiguration в класс Application, как это было предложено в другом месте, но он не работает.
Моя конфигурация безопасности выглядит следующим образом:
@Configuration
@Profile("production")
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Value("${adDomain}")
private String adDomain;
@Value("${adUrl}")
private String adUrl;
@Value("${rootDn}")
private String rootDn;
@Value("${searchFilter}")
private String searchFilter;
private final AuthenticationManagerBuilder auth;
private final SessionRepository sessionRepository;
@Autowired
public SecurityConfiguration(AuthenticationManagerBuilder auth, SessionRepository sessionRepository) {
this.auth = auth;
this.sessionRepository = sessionRepository;
}
@Override
public void configure(WebSecurity webSecurity) throws Exception
{
webSecurity
.ignoring()
// All of Spring Security will ignore the requests
.antMatchers("/static/**", "/api/web/logout")
.antMatchers(HttpMethod.POST, "/api/web/login");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable() // Using JWT there is no need for CSRF-protection!
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthorizationFilter(authenticationManagerBean(), sessionRepository));
}
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
ActiveDirectoryLdapAuthenticationProvider adProvider =
new ActiveDirectoryLdapAuthenticationProvider(adDomain, adUrl, rootDn);
adProvider.setConvertSubErrorCodesToExceptions(true);
adProvider.setUseAuthenticationRequestCredentials(true);
adProvider.setSearchFilter(searchFilter);
adProvider.setUserDetailsContextMapper(new InetOrgPersonContextMapper());
auth.authenticationProvider(adProvider);
return super.authenticationManagerBean();
}
}
Метод контроллера выглядит следующим образом
@RequestMapping(path = "/licenses", method = RequestMethod.GET)
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<?> getAllLicenses(@RequestParam("after") int pagenumber, @RequestParam("size") int pagesize
, @RequestParam("searchText") String searchText) {
List<LicenseDTO> result = ...
return new ResponseEntity<Object>(result, HttpStatus.OK);
}
Я совершенно уверен, что упускаю что-то очень простое, но просто не могу понять, что.
Кстати: еслипользователь, запрашивающий лицензии, имеет роль ADMIN, все работает, как и ожидалось, поэтому проблема не в 404.