Пользователь может получить доступ к ресурсу, даже если он не является частью «@Secured ([роль])»

#spring-security #spring-boot

#spring-безопасность #spring-boot

Вопрос:

Я хотел бы защитить свою конечную точку, чтобы только пользователи с ролью READ могли получить доступ к определенному ресурсу. Это мои конфигурации:

Контроллер:

 @RestController
@RequestMapping("/api/status")
public class StatusController {

    @RequestMapping(method = RequestMethod.GET)
    @Secured("READ")
    Map<String, Object> getSecureStatus() {
        Map<String, Object> statusMap = new LinkedHashMap<>();

        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        statusMap.put("auth", auth);
        return statusMap;
    }
}
  

WebSecurityConfigurerAdapter:

 @Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
             // .antMatchers("/").permitAll()
                .antMatchers("/api/**").authenticated()
                .and()
            .httpBasic();
    }
}
  

GlobalAuthenticationConfigurerAdapter:

 @Configuration
public class AuthenticationManagerConfig extends
        GlobalAuthenticationConfigurerAdapter {

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("teddy").password("password").roles("USER");
    }

}
  

Я бы предположил, что Тедди не должен иметь доступа к ресурсу, поскольку его роль — ПОЛЬЗОВАТЕЛЬ, а не ЧТЕНИЕ.

Но с помощью этого вызова Тедди все равно получает свою информацию: curl -u teddy:password 'http://localhost:8080/api/status/' :

 {
  "auth": {
    "details": {
      "remoteAddress": "127.0.0.1",
      "sessionId": null
    },
    "authorities": [
      {
        "authority": "ROLE_USER"
      }
    ],
    "authenticated": true,
    "principal": {
      "password": null,
      "username": "teddy",
      "authorities": [
        {
          "authority": "ROLE_USER"
        }
      ],
      "accountNonExpired": true,
      "accountNonLocked": true,
      "credentialsNonExpired": true,
      "enabled": true
    },
    "credentials": null,
    "name": "teddy"
  }
}
  

Чего мне не хватает?

Редактировать: удалено .antMatchers("/").permitAll()

Ответ №1:

Вероятно, это потому, что вы используете .antMatchers("/").permitAll() его, сообщая spring, что вы разрешаете каждый запрос.

Попробуйте удалить его из своей конфигурации.

Комментарии:

1. Спасибо за подсказку, но, к сожалению, поведение остается тем же, даже если я удаляю строку.

Ответ №2:

Я нашел ошибку. Я упустил из виду, что это getSecureStatus() явно не определено public . Этот код исправляет это:

 @RestController
@RequestMapping("/api/status")
public class StatusController {

    @RequestMapping(method = RequestMethod.GET)
    @Secured("READ")
    public Map<String, Object> getSecureStatus() {
        Map<String, Object> statusMap = new LinkedHashMap<>();

        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        statusMap.put("auth", auth);
        return statusMap;
    }
}