How to override role for a specific endpoint in Spring Security?

Coffemanz :

I'm setting up security configuration with the help of Spring Security.

I'm interested if it's possible to override a role for a more specific endpoint with the help of HttpSecurity object.

Let's say I have something like this:

httpSecurity
               .authenticationProvider(authenticationProvider)
               .authorizeRequests()
               .antMatchers("/api/v1/**").hasRole("ADMIN")

And I want to have another role for a more specific endpoint:

httpSecurity
                .authenticationProvider(authenticationProvider)
                .authorizeRequests()
                .antMatchers("/api/v1/**").hasRole("ADMIN")
                .antMatchers("/api/v1/specific").hasRole("ROLE_ONLY_FOR THIS_ENDPOINT")

Ans it doesn't work, it still requires ADMIN role for the specific endpoint.

Is it possible to override it somehow or exclude this endpoint from a more common role rule?

Update 1:

    @PreAuthorize("hasAuthority('ROLE_SPECIFIC')")
    @GetMapping("/specific")
    public ResponseEntity<TopDamagedComponentsResponse> getTopDamagedComponents(
            @RequestParam(required = true) String manufacturer,
            @RequestParam(required = true) String model,
            @RequestParam(required = true) String vehicleBodyType,
            @RequestParam(required = true) String vehicleType,
            @RequestParam(defaultValue = "25", required = false) Integer limit){
        List<ComponentDto> topDamagedComponents = service.getTopDamagedComponents(manufacturer, model, vehicleBodyType, vehicleType, limit);
        TopDamagedComponentsFilter filter = new TopDamagedComponentsFilter(manufacturer, model, vehicleBodyType, vehicleType);
        return new ResponseEntity<TopDamagedComponentsResponse>(new TopDamagedComponentsResponse(topDamagedComponents, topDamagedComponents.size(), filter), HttpStatus.OK);
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .addFilterBefore(tokenAuthFilter, BasicAuthenticationFilter.class)
                .antMatcher("/**")
                .authenticationProvider(authenticationProvider)
                .authorizeRequests()


                .antMatchers("/api/v1/**").hasRole("ADMIN")

                .antMatchers("/v2/api-docs", "/swagger-resources/configuration/ui", "/swagger-resources", "/swagger-resources/configuration/security", "/swagger-ui.html", "/webjars/**").permitAll()

                .antMatchers("/actuator/**").permitAll()

                .and()
                  .sessionManagement()
                      .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.csrf().disable();


    }

I've tried to use @PreAuthorize but it still doesn't work.

Coffemanz :

Thanks @R.G for noticing a typo. I was missing / in the beginning of my endpoint (api/v1/specific), it was like this:

httpSecurity
                .authenticationProvider(authenticationProvider)
                .authorizeRequests()
                .antMatchers("api/v1/specific").hasRole("ROLE_ONLY_FOR THIS_ENDPOINT")
                .antMatchers("/api/v1/**").hasRole("ADMIN")

After adding / and putting rules in the right order in the chain (more specific ones should go first and more general ones should be in the end of the chain), it works as expected: a specific endpoint requires only a specific role and all the others under /api/v1/** require an admin role.

Finally it looks this way:

httpSecurity
                .authenticationProvider(authenticationProvider)
                .authorizeRequests()
                .antMatchers("/api/v1/specific").hasRole("ROLE_ONLY_FOR THIS_ENDPOINT")
                .antMatchers("/api/v1/**").hasRole("ADMIN")

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=357119&siteId=1