Spring Security: Granted Authority

Spring Security, a comprehensive framework for securing Spring-based applications, introduces a robust model for handling permissions through the concept of Granted Authority. This blog post will explore what Granted Authority is, its role within Spring Security, and how to effectively implement and utilize it with practical examples.

Understanding Granted Authority in Spring Security

Granted Authority represents permission or a right granted to an authenticated user to perform specific actions within an application. It is a core component of Spring Security's authorization mechanism, enabling fine-grained access control based on the roles or authorities assigned to the user.

The Role of Granted Authority

Permission-Based Access Control: Granted Authorities can be used to restrict access to various parts of your application based on the user's permissions.

Flexibility and Scalability: Authorities can represent roles (like ROLE_USER, ROLE_ADMIN) or finer-grained permissions (like READ_PRIVILEGES, WRITE_PRIVILEGES), offering flexibility to model complex security requirements.

Implementing Granted Authority

Implementing Granted Authority in Spring Security involves defining the authorities or roles, assigning them to users, and enforcing access control based on these authorities. 

Here are some examples to demonstrate these steps.

Example 1: Defining Authorities in UserDetailsService

When implementing UserDetailsService, you define the authorities granted to each user. This setup is crucial for associating users with their roles or permissions.
@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // Example: Fetch user and roles from the database
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found");
        }
        List<GrantedAuthority> authorities = user.getRoles().stream()
                .map(role -> new SimpleGrantedAuthority(role.getName()))
                .collect(Collectors.toList());

        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
    }
}

This example fetches users and their roles from the database, converting each role to a GrantedAuthority

Example 2: Configuring Method Security Using Authorities 

Spring Security allows you to secure service methods using annotations like @PreAuthorize, where you can specify the required authorities for method access.
@RestController
@RequestMapping("/api/")
public class AdminController {

    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/admin")
    public ResponseEntity<String> helloAdmin(){
        return ResponseEntity.ok("Hello Admin");
    }

    @PreAuthorize("hasRole('USER')")
    @GetMapping("/user")
    public ResponseEntity<String> helloUser(){
        return ResponseEntity.ok("Hello User");
    }
}
@PreAuthorize("hasRole('ADMIN')"): This is applied to the helloAdmin() method. It specifies that this endpoint can only be accessed by users with the 'ADMIN'. 

PreAuthorize("hasRole('USER')"): This annotation on the helloUser() method restricts access to users with the 'USER' role. Spring Security enforces this role check before allowing access to the method. 

Using @PreAuthorize in Spring Boot REST APIs provides a powerful and flexible way to manage access control at the method level. It allows for clear and maintainable security configurations directly in the context of the resources they protect.

Example 3: Securing Web Endpoints by Authorities

You can also use authorities to restrict access to specific web routes or endpoints within your application.
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable())
                .authorizeHttpRequests((authorize) -> {
                    authorize.requestMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
                    authorize.requestMatchers("/user/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")
                    authorize.requestMatchers("/public/**").permitAll()
                    authorize.anyRequest().authenticated();
                }).httpBasic(Customizer.withDefaults());
        return http.build();
    }
}
This configuration limits access to the /admin/** paths to users with the ROLE_ADMIN authority, while /user/** paths are accessible to users with either ROLE_USER or ROLE_ADMIN

Conclusion 

Granted Authority in Spring Security offers a powerful and flexible mechanism for managing user permissions and securing your application. Developers can implement comprehensive security models that align with their application's requirements by understanding how to define, assign, and enforce authorities. Whether restricting access to specific methods, endpoints, or actions within your application, leveraging Granted Authorities enables you to maintain a secure, permission-based access control system that scales with your application's complexity and growth.

Comments