Spring Security, Method Security annotation (@Secu

2020-05-23 02:18发布

I am trying to set up a method security annotation using @Secured("ADMIN") (without any XML, only java config, Spring Boot). But access via roles does not work.

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);
    }

.....

}

I want restrict access to the method of the controller:

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

    @Autowired
    private GroupService groupService;

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

}

Restrict access by the url is working, with:

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

Maybe I forgot to specify that I want restrict by roles?

UPD: By the rules, At what layer must be @PreAuthorize("hasRole('ADMIN')") in Controller layer or in Service layer?

7条回答
太酷不给撩
2楼-- · 2020-05-23 03:21

I know this thread is quite old and my answer alludes to portions of the answers by various people in this thread; but here is a list combined list of pitfalls and answers:

  1. When using @Secured, and the role name is (e.g.) ADMIN; this means an annotation of @Secured("ROLE_ADMIN").
  2. WebSecurityConfigurerAdapter must have @EnableGlobalMethodSecurity(securedEnabled = true)
  3. As with most Spring related proxies, make sure that the class and the secured methods are not in any way final. For Kotlin this means "open" every method as well as the class.
  4. When the class and its methods are virtual ("open"), then there is no implied need for an interface.

Here is part of a working Kotlin example:

@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 { ... 
    }

and

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

Regards

查看更多
登录 后发表回答