You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security基于权限而非角色的授权配置问题咨询

Correct Authorization Configuration for Spring Security (Permission-Based)

Alright, let's tackle this Spring Security authorization issue you're facing. The problem here is that your current setup isn't properly enforcing the required permission combinations for Page A, which is why users with the User role can access it. Let's fix this step by step.

First, let's align on your requirements:

  • Page A: Requires all three permissions (ADD, VIEW, EDIT) — only Admin and Manager have these
  • Page B: Requires both ADD and VIEW permissions — all three user types qualify

Step 1: Ensure Permissions Are Properly Assigned to Roles

First, you need to make sure your UserDetailsService correctly maps each role to its corresponding permissions. Don't just add role authorities—include the specific permissions too. Here's a sample implementation:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // Replace with your actual user retrieval logic (e.g., database call)
        return switch (username) {
            case "admin" -> new User(
                "admin",
                "{noop}admin123", // {noop} for plain text passwords (remove in production)
                AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ADD", "EDIT", "VIEW")
            );
            case "manager" -> new User(
                "manager",
                "{noop}manager123",
                AuthorityUtils.createAuthorityList("ROLE_MANAGER", "ADD", "EDIT", "VIEW")
            );
            case "user" -> new User(
                "user",
                "{noop}user123",
                AuthorityUtils.createAuthorityList("ROLE_USER", "ADD", "VIEW")
            );
            default -> throw new UsernameNotFoundException("User not found: " + username);
        };
    }
}

Step 2: Configure Authorization Rules with Permission Checks

Now, update your SecurityFilterChain to use permission-based checks instead of role-based ones. Use hasAllAuthorities() to enforce that a user must possess all specified permissions to access a resource:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                // Page A: Require ALL of ADD, VIEW, EDIT permissions
                .requestMatchers("/page-a/**").hasAllAuthorities("ADD", "VIEW", "EDIT")
                // Page B: Require both ADD and VIEW permissions
                .requestMatchers("/page-b/**").hasAllAuthorities("ADD", "VIEW")
                // Allow anonymous access to login page (adjust as needed)
                .requestMatchers("/login").permitAll()
                // All other routes require authentication
                .anyRequest().authenticated()
            )
            .formLogin(form -> form.permitAll()) // Enable form login
            .logout(logout -> logout.permitAll()); // Enable logout

        return http.build();
    }
}

Why This Fixes Your Issue

The problem you were seeing (User accessing Page A) likely came from one of these mistakes:

  1. You were using role-based checks like hasAnyRole("ADMIN", "MANAGER") but had misconfigured role assignments.
  2. You used hasAnyAuthority() instead of hasAllAuthorities(), which would allow users with any of the permissions (not all) to access Page A.
  3. Your UserDetailsService wasn't correctly assigning permissions to roles (e.g., accidentally giving User the EDIT permission).

With the above setup:

  • Users with the User role only have ADD and VIEW permissions, so they fail the hasAllAuthorities("ADD", "VIEW", "EDIT") check for Page A.
  • All users (Admin, Manager, User) pass the hasAllAuthorities("ADD", "VIEW") check for Page B, as expected.

Alternative: Using SpEL Expressions

If you prefer, you can use Spring Expression Language (SpEL) for more flexibility. The equivalent rules would be:

.requestMatchers("/page-a/**").access("hasAuthority('ADD') and hasAuthority('VIEW') and hasAuthority('EDIT')")
.requestMatchers("/page-b/**").access("hasAuthority('ADD') and hasAuthority('VIEW')")

This works exactly the same as hasAllAuthorities(), but gives you more control if you need to add complex logic later.

内容的提问来源于stack exchange,提问作者vikas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:39:05