0Pricing
Spring Boot 4 Microservices & REST APIs · Lekcja

Kontrola dostępu oparta na rolach

Skonfigurują Państwo autoryzację opartą na rolach, aby precyzyjnie definiować uprawnienia dostępu dla różnych ról użytkowników.

Kontrola dostępu oparta na rolach to bezpłatna lekcja Spring Boot 4 Microservices & REST APIs na CoddyKit. To lekcja 3 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Spring Boot 4 Microservices & REST APIs, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Spring Boot 4 Microservices & REST APIs zawiera 3 lekcji w sumie.

Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.

Intro to Role-Based Access

Role-Based Access Control (RBAC) is a method of restricting system access based on the roles of individual users.

Instead of assigning permissions directly to users, you assign permissions to roles, and then assign roles to users.

  • Simplifies security management.
  • Improves security policy enforcement.
  • Easier to audit and maintain.

Benefits of RBAC

RBAC offers several advantages for securing your applications:

  • Scalability: Easily manage access for many users and resources as your application grows.
  • Flexibility: Roles can be changed or updated without modifying individual user permissions.
  • Compliance: Helps meet regulatory requirements by clearly defining who can do what.

Representing User Roles

In Spring Security, roles are typically represented as simple strings, often prefixed with ROLE_ (e.g., ROLE_ADMIN, ROLE_USER).

It's good practice to define these as constants or enums to avoid typos.

public enum UserRole {
  ADMIN,
  USER
}

Spring Security automatically adds the ROLE_ prefix when you use expressions like hasRole('ADMIN').

public enum UserRole {
  ADMIN,
  USER
}

Basic Security Setup

To enable method-level security and configure users with roles, we set up a SecurityFilterChain bean.

This example defines an in-memory user 'admin' with ROLE_ADMIN and 'user' with ROLE_USER.

package com.coddykit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true) // Enable @PreAuthorize
public class RbacApplication {

    public static void main(String[] args) {
        SpringApplication.run(RbacApplication.class, args);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .httpBasic(org.springframework.security.config.Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails admin = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("password")
            .roles("ADMIN")
            .build();
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(admin, user);
    }
}

@RestController
class PlaceholderController {
    @GetMapping("/")
    public String home() {
        return "Welcome to RBAC Demo!";
    }
}

Applying Role Constraints

Spring Security's @PreAuthorize annotation allows you to define access rules directly on controller methods.

It uses Spring Expression Language (SpEL) to evaluate conditions before a method is executed.

@PreAuthorize("hasRole('ADMIN')")

This ensures only users with the ADMIN role can call the method.

@PreAuthorize("hasRole('ADMIN')")

Exclusive Admin Access

Let's create an endpoint that only users with the ADMIN role can access. If a USER tries to access it, they will get a 403 Forbidden error.

package com.coddykit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class RbacApplication {

    public static void main(String[] args) {
        SpringApplication.run(RbacApplication.class, args);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .httpBasic(org.springframework.security.config.Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails admin = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("password")
            .roles("ADMIN")
            .build();
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(admin, user);
    }
}

@RestController
class AdminController {

    @GetMapping("/admin/dashboard")
    @PreAuthorize("hasRole('ADMIN')")
    public String getAdminDashboard() {
        return "Welcome, Admin! This is your dashboard.";
    }

    @GetMapping("/")
    public String home() {
        return "Welcome to RBAC Demo!";
    }
}

Granting Multiple Roles

Sometimes, an endpoint should be accessible by more than one role. You can use hasAnyRole() for this.

For example, a dashboard might be visible to both ADMIN and regular USER roles.

package com.coddykit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class RbacApplication {

    public static void main(String[] args) {
        SpringApplication.run(RbacApplication.class, args);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .httpBasic(org.springframework.security.config.Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails admin = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("password")
            .roles("ADMIN")
            .build();
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(admin, user);
    }
}

@RestController
class MultiRoleController {

    @GetMapping("/dashboard")
    @PreAuthorize("hasAnyRole('ADMIN', 'USER')")
    public String getUserDashboard() {
        return "Hello! Welcome to your dashboard.";
    }

    @GetMapping("/admin/settings")
    @PreAuthorize("hasRole('ADMIN')")
    public String getAdminSettings() {
        return "Admin settings page.";
    }

    @GetMapping("/")
    public String home() {
        return "Welcome to RBAC Demo!";
    }
}

Custom Access Decisions

While hasRole() and hasAnyRole() cover many cases, Spring Security allows more complex access rules.

You can use SpEL to check multiple conditions, like hasRole('ADMIN') and hasIpAddress('192.168.1.0/24').

For very complex or dynamic logic, you can implement custom PermissionEvaluator beans.

Testing Your RBAC

You can test your RBAC configuration by running your Spring Boot application and using a tool like Postman or curl:

  • Log in as 'admin' (user: admin, pass: password) and try to access all endpoints.
  • Log in as 'user' (user: user, pass: password) and verify access to user endpoints, but not admin-only ones.
  • Try without authentication to see if it's rejected.

RBAC Access Check

Consider the following Spring Security configuration and controller method:

@Configuration
@EnableMethodSecurity(prePostEnabled = true)
// ... other config ...

@Bean
public UserDetailsService userDetailsService() {
    UserDetails userA = User.withDefaultPasswordEncoder()
        .username("alice").password("pw").roles("USER").build();
    UserDetails userB = User.withDefaultPasswordEncoder()
        .username("bob").password("pw").roles("MANAGER").build();
    return new InMemoryUserDetailsManager(userA, userB);
}

@RestController
class MyController {
    @GetMapping("/report")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public String getReport() {
        return "Confidential Report";
    }
}

Which user(s) can successfully access the /report endpoint?

@Configuration
@EnableMethodSecurity(prePostEnabled = true)
// ... other config ...

@Bean
public UserDetailsService userDetailsService() {
    UserDetails userA = User.withDefaultPasswordEncoder()
        .username("alice").password("pw").roles("USER").build();
    UserDetails userB = User.withDefaultPasswordEncoder()
        .username("bob").password("pw").roles("MANAGER").build();
    return new InMemoryUserDetailsManager(userA, userB);
}

@RestController
class MyController {
    @GetMapping("/report")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public String getReport() {
        return "Confidential Report";
    }
}

RBAC Lesson Summary

In this lesson, we explored Role-Based Access Control (RBAC) in Spring Boot Microservices.

  • We learned how to define and assign roles to users.
  • We configured Spring Security to recognize these roles using SecurityFilterChain.
  • We used @PreAuthorize with hasRole() and hasAnyRole() to secure API endpoints based on user roles.

RBAC is a powerful way to manage access control efficiently and securely in your applications.

Często zadawane pytania

Czy lekcja „Kontrola dostępu oparta na rolach” jest bezpłatna?

Tak — pełny tekst „Kontrola dostępu oparta na rolach” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Spring Boot 4 Microservices & REST APIs, przejdź na CoddyKit PRO. Kurs Spring Boot 4 Microservices & REST APIs zawiera 3 lekcji w sumie.

Co nauczysz się w „Kontrola dostępu oparta na rolach”?

Skonfigurują Państwo autoryzację opartą na rolach, aby precyzyjnie definiować uprawnienia dostępu dla różnych ról użytkowników. Ćwiczysz Spring Boot 4 Microservices & REST APIs z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Spring Boot 4 Microservices & REST APIs?

Nie wymagamy żadnego doświadczenia. Spring Boot 4 Microservices & REST APIs w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 3.

Ile czasu zajmuje lekcja „Kontrola dostępu oparta na rolach”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Spring Boot 4 Microservices & REST APIs?

Tak. Każda lekcja Spring Boot 4 Microservices & REST APIs zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podstawy OAuth2 i JWT
  2. Zabezpieczanie punktów końcowych REST
  3. Kontrola dostępu oparta na rolach
← Powrót do Spring Boot 4 Microservices & REST APIs