Spring Security,Method Security annotation(@Secured)is not working(java config)

t3psigkw  于 2023-06-21  发布在  Spring
关注(0)|答案(8)|浏览(139)

我正在尝试使用@Secured(“ADMIN”)设置一个方法安全注解(没有任何XML,只有Java配置,Sping Boot )。但是通过角色访问不起作用。
安全配置:

@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")

也许我忘了指定我想按角色限制?

**UPD:**根据规则,@PreAuthorize("hasRole('ADMIN')")必须在控制器层还是服务层的哪个层?

bjg7j2ky

bjg7j2ky1#

请加上这个

@EnableGlobalMethodSecurity(securedEnabled = true)

此元素用于在应用程序中启用基于注解的安全性(通过在元素上设置适当的属性),并将安全切入点声明组合在一起,这些声明将应用于整个应用程序上下文,特别是@Secured。因此,您的代码应该如下所示

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

yqkkidmi2#

我知道这个帖子已经很老了,我的回答暗示了这个帖子中不同人的部分答案;但这里有一个陷阱和答案的综合列表:
1.使用@Secured时,角色名称为(例如)ADMIN;这意味着@Secured(“ROLE_ADMIN”)的注解。

  1. WebSecurityConfigurerAdapter必须具有@EnableGlobalMethodSecurity(securedEnabled = true)
    1.与大多数Spring相关的代理一样,确保类和受保护的方法不是final的。对于Kotlin来说,这意味着“打开”每个方法以及类。
    1.当类和它的方法是虚拟的(“开放”),那么就不需要接口了。
    下面是一个Kotlin示例的一部分:
@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() {

问候

yks3o0rb

yks3o0rb3#

控制器上的方法安全性不起作用的原因可能有很多。
首先,因为它从未在Spring Security手册中作为示例引用...开个玩笑,但是把Spring工具带到他们不想去的地方可能很棘手。
更严重的是,你应该像@Mudassar所说的那样启用方法安全性。手册上说:

  • 我们可以在任何@Configuration示例上使用@EnableGlobalMethodSecurity注解启用基于注解的安全性。例如,下面将启用Spring Security的@Secured annotation。
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
   // ...
}

请注意,Mudassar的答案直到这里都是正确的。
但是方法安全性是基于AOP的,默认情况下在接口上使用JDK代理。这就是为什么所有示例都在服务层应用方法安全性的原因,因为服务类通常作为接口注入控制器。
你当然可以在控制器层使用它,但是:

  • 或者你的所有控制器都为你实现了所有@Secured注解方法的接口
  • 或者必须切换到类代理

我尝试遵循的规则是:

  • 如果我想保护一个URL,我坚持使用HTTPSecurity
  • 如果我需要允许更细粒度的访问,我会在服务层添加安全性
5lhxktic

5lhxktic4#

这个问题解决了。
我加@EnableGlobalMethodSecurity(prePostEnabled = true)

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

在控制器中,我将@Secured("ADMIN")更改为@PreAuthorize("hasRole('ADMIN')")

yi0zb3m4

yi0zb3m45#

我想分享我的决定,也许会有帮助。
使用spring mvc+spring security,版本4.2.9.RELEASE
例如,我有一个方法注解为@Secured的Service

@Secured("ACTION_USER_LIST_VIEW")
List<User> getUsersList();

但是,它没有工作,因为GlobalMethodSecurityConfiguration有内部方法。

protected AccessDecisionManager accessDecisionManager()

其中使用默认的rolePrefix = "ROLE_"; * 初始化了new RoleVoter()(这使得无法使用bean来设置rolePrefix)*,这给予了我们不工作的注解,因为RoleVoter期望以**'ROLE_'开头的注解值
为了解决这个问题,我像这样覆盖
GlobalMethodSecurityConfiguration**

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class AppMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
    @Override
    protected AccessDecisionManager accessDecisionManager() {
        List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
        ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
        expressionAdvice.setExpressionHandler(getExpressionHandler());
        decisionVoters.add(getRoleVoter());
        decisionVoters.add(new AuthenticatedVoter());
        return new AffirmativeBased(decisionVoters);
    }

    private RoleVoter getRoleVoter() {
        RoleVoter e = new RoleVoter();
        e.setRolePrefix("");
        return e;
    }
}
jaql4c8m

jaql4c8m6#

您需要使用@secured(ROLE_ADMIN)而不是@secured(ADMIN)。您需要在您的角色名称前面写上**“ROLE_”**。请找到下面提到的示例,该示例确保只有具有Admin角色的用户才能访问list()方法。

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

    @Autowired
    private GroupService groupService;

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

}
dwthyt8l

dwthyt8l7#

也许您应该将AppSecurityConfiguration注册到与WebMvcConfig(扩展WebMvcConfigurerAdapter)相同的上下文。

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

relj7zay8#

花了几个小时,终于想通了。服务层的方法级安全工作,使用Spring Security 5.7.8版本。
我将@PreAuthorize注解从控制器类移动到服务类,然后为我工作。

相关问题