What is the approach to provide access of resources for different Role?

501 Views Asked by At

I am configuring spring security in my project using jwt token. I am sucessfully generated jwt token and accessing it from front end.

In my spring boot REST APT I have several controllers with all CRUD methods. I want to give access of get method to all the users and even to public, while for POST,PUT and Delete I want to give access to only admin and moderator depending on the case. But for some POST method like in inquiry form i want to give access to all users.

What approach should I follow for that, Do i need to write

@PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")

for each method in each controller.

Right now i just build a test page to check access of roles .

package com.panchmeru_studio.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api/test")
public class TestController {
    @GetMapping("/all")
    public String allAccess() {
        return "Public Content.";
    }
    
    @GetMapping("/user")
    @PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
    public String userAccess() {
        return "User Content.";
    }

    @GetMapping("/mod")
    @PreAuthorize("hasRole('MODERATOR')")
    public String moderatorAccess() {
        return "Moderator Board.";
    }

    @GetMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public String adminAccess() {
        return "Admin Board.";
    }
}

Securityconfig.java

package com.panchmeru_studio.security.jwt;

import com.panchmeru_studio.filter.AuthTokenFilter;
import com.panchmeru_studio.security.service.ApplicationUserDetailsService;
import com.panchmeru_studio.security.service.MyUserDetailsService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.server.authorization.AuthorizationWebFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import static com.panchmeru_studio.constants.SecurityConstants.SIGN_UP_URL;

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

    private MyUserDetailsService userDetailsService;
   // private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private AuthEntryPointJwt unauthorizedHandler;
    @Bean
    public AuthTokenFilter authenticationJwtTokenFilter() {
        return new AuthTokenFilter();
    }

    public SecurityConfiguration(MyUserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
       // this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
        .authorizeRequests().antMatchers("/api/auth/**").permitAll()
        .antMatchers("/api/test/**").permitAll()
        .anyRequest().authenticated().and()
    //   .addFilter(new AuthenticationFilter(authenticationManager()))
    //     .addFilter(new AuthorizationFilter(authenticationManager()))
        .exceptionHandling().authenticationEntryPoint(unauthorizedHandler);
       // .authorizeRequests().antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
//                .anyRequest().authenticated()
//                .and()
               
        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
        return source;
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
    
    @Bean
    public PasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }
    


    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


}

Now for example i have 10 controllers, Project ,AboutUS , ProjectCategory,Gallery Each has different url(Request mapping) so, Do i need to assign @PreAuthorize to each method to each controller and then give request mapping of each controller to security config to give authrization?

1

There are 1 best solutions below

0
On

If you want to base the access to methods only on user roles, then the approach you described is the correct one.

Since you're using JWTs to authorize access to your APIs, you could secure the APIs based on claims in JWTs instead of the user profile. In such a setup you don't need access to user accounts at all, you make all the decisions based on what is in the JWT. Have a look at this example to see how to set this up in a Spring API.