2015-07-02 4 views
9

Я пытаюсь настроить аннотацию безопасности метода с помощью @Secured («ADMIN») (без какого-либо XML, только java config, Spring Boot) , Но доступ через роли не работает.Spring Security, метод Аннотации безопасности (@Secured) не работает (java config)

Security Config:

@Configuration 
@EnableWebSecurity 
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{ 

..... 

@Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .authorizeRequests() 
       .antMatchers("/api/**").fullyAuthenticated().and() 
       .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); 
    } 

..... 

} 

Я хочу, чтобы ограничить доступ к методу контроллера:

@RestController 
@RequestMapping("/api/groups") 
public class GroupController { 

    @Autowired 
    private GroupService groupService; 

    @Secured("ADMIN") 
    @RequestMapping 
    public List<Group> list() { 
     return groupService.findAll(); 
    } 

} 

Ограничить доступ к URL-адресу работает с:

.antMatchers("/api/**").hasAuthority("ADMIN") 

Maybe Я забыл указать, что хочу ограничить роли?

UPD: По правилам, на какой слой должен быть @PreAuthorize("hasRole('ADMIN')") в слое контроллера или в слое службы?

+0

Что не работает? Разве браузеры не пытаются вас аутентифицировать? Не игнорирует ли эти полномочия учетные данные? Кстати: вы также должны опубликовать, где вы привязываете своего пользователя к группе администратора, возможно, это проблемная область. – Marged

+1

Аутентификация работает правильно, но любой пользователь с любой ролью имеет доступ к «/ api/groups» – silverhawk

+1

Где вы устанавливаете ROLE 'ADMIN', можете ли вы показать мне это? –

ответ

0

Эта проблема была решена.

добавить @EnableGlobalMethodSecurity(prePostEnabled = true)

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{ 
} 

И в контроллере я изменил @Secured("ADMIN") к @PreAuthorize("hasRole('ADMIN')")

17

Пожалуйста, добавьте эту

@EnableGlobalMethodSecurity(securedEnabled = true) 

Этот элемент используется для включения аннотации на основе безопасности в вашем приложении (путем установки соответствующих атрибутов элемента), а также группироваться декларациями Pointcut безопасности, которые будут применяться по всему вашему контексту приложения специально для @Secured. Поэтому ваш код должен выглядеть следующим образом

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(securedEnabled = true) 
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{.. 
+0

сделал редактирование для специально protectedEnabled = true – Mudassar

+0

Я пытаюсь это сделать, но это не работает правильно, т.е. пружинный ответ «Access denied» – silverhawk

+0

Давайте сделаем некоторый анализ, любую выживающую причину добавления @RequestMapping ниже Secured («ADMIN») – Mudassar

10

Там может быть много причин, по которым метод защиты на контроллере не работает.

Во-первых, поскольку это никогда не цитируется в качестве примера в руководстве по безопасности Spring ... шутка, но может быть сложно использовать инструменты Spring, где они не хотят идти.

Более серьезно, вы должны включить защиту метода, как уже говорилось в @Mudassar. В руководстве написано:

Мы можем включить защиту на основе аннотаций, используя аннотацию @EnableGlobalMethodSecurity на любом экземпляре @Configuration. Например, следующее будет содержать примечание @Secured Spring Security.

@Configuration 
@EnableGlobalMethodSecurity(securedEnabled = true) 
public class MethodSecurityConfig { 
    // ... 
} 

Обратите внимание, что ответ Mudassar правилен до здесь.

Но метод безопасности основан на AOP, который по умолчанию использует проксирование JDK на интерфейсах . Именно поэтому все примеры применяют защиту метода на уровне сервиса, поскольку классы обслуживания обычно вводятся в контроллеры как интерфейсы.

Вы, конечно, можете использовать его на контроллер слое, но:

  • либо все контроллеры реализовывать интерфейсы для вас всех @Secured аннотированных метод
  • или вы должны переключиться на класс проксирование

Правило, которое я пытаюсь выполнить, следующее:

  • если я хочу ecure в URL, я придерживаюсь HTTPSecurity
  • , если мне нужно, чтобы тонкоуровневого доступ, добавляю безопасность на уровне услуг
0

Может быть, вы должны зарегистрировать свой AppSecurityConfiguration в том же контексте, как WebMvcConfig (который расширяет WebMvcConfigurerAdapter).

AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();  
mvcContext.register(WebMvcConfig.class, SecurityConfig.class); 
5

Я знаю, что эта ветка довольно старая, и мой ответ ссылается на части ответов различных людей в этой теме; но вот список, объединенный список ошибок и ответов:

  1. При использовании @Secured и имени роли (например) ADMIN; это означает аннотацию @Secured («ROLE_ADMIN»).
  2. WebSecurityConfigurerAdapter должен @EnableGlobalMethodSecurity (securedEnabled = TRUE)
  3. Как и большинство Spring связанной прокси, убедитесь, что класс и обеспеченные методы никоим образом не окончательным. Для Котлина это означает «открыть» каждый метод, а также класс.
  4. Когда класс и его методы являются виртуальными («открытыми»), тогда нет необходимости в интерфейсе.

Вот часть рабочего примера Котлин:

@RestController 
@RequestMapping("api/v1") 

    open class DiagnosticsController { 
     @Autowired 
     lateinit var systemDao : SystemDao 

     @RequestMapping("ping", method = arrayOf(RequestMethod.GET)) 
     @Secured("ROLE_ADMIN") 
     open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ... 
    } 

и

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(securedEnabled = true) 
open class WebSecurityConfig : WebSecurityConfigurerAdapter() { 

С уважением

0

Вы должны использовать @Secured (ROLE_ADMIN) вместо @Secured (ADMIN). Вы должны написать «ROLE_» infront вашего имени роли. Пожалуйста, найдите приведенный ниже пример, который гарантирует, что только пользователь с ролью администратора может получить доступ к методу list().

@RestController 
@RequestMapping("/api/groups") 
public class GroupController { 

    @Autowired 
    private GroupService groupService; 

    @Secured("ROLE_ADMIN") 
    @RequestMapping 
    public List<Group> list() { 
     return groupService.findAll(); 
    } 

} 
Смежные вопросы