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

Spring Boot中@PreAuthorize结合Microsoft Entra ID权限控制失效问题

解决Spring Boot结合Microsoft Entra ID使用@PreAuthorize失效问题

核心问题分析

@PreAuthorize未生效主要由以下原因导致:

  • 未启用Spring Security方法级安全控制
  • 新旧Azure AD依赖版本冲突
  • Entra ID角色与Spring Security权限未正确映射
  • 缺少Entra ID必要配置

分步解决方案

1. 清理依赖冲突

删除旧版Azure AD starter,保留适配Spring Boot 3.x的新版依赖,修改后的依赖如下:

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'com.azure.spring:spring-cloud-azure-starter-active-directory:5.12.0'

注:spring-cloud-azure-starter-active-directory已包含OAuth2客户端相关依赖,无需重复引入。

2. 启用方法级安全

在启动类或单独的Security配置类上添加@EnableMethodSecurity注解,开启方法级权限控制:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@EnableMethodSecurity // 新增此注解
public class ProaccountRestApplication {

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

    @GetMapping("/home")
    @PreAuthorize("hasAuthority('Admin')") // 先改用hasAuthority适配默认角色格式
    public String getHome (){
        return "Yes";
    }
}

3. 配置Microsoft Entra ID参数

在application.yml中添加Entra ID的租户、客户端信息:

spring:
  cloud:
    azure:
      active-directory:
        enabled: true
        credential:
          client-id: <你的Entra ID客户端ID>
          client-secret: <你的Entra ID客户端密钥>
        profile:
          tenant-id: <你的Entra ID租户ID>
        resource-server:
          jwt:
            enabled: true
            issuer-uri: https://login.microsoftonline.com/<租户ID>/v2.0
            claim-set-mapping:
              roles: roles # 映射Entra ID返回的roles声明到Spring Security权限

4. 自定义JWT角色映射(可选)

如果想继续使用hasRole('Admin')表达式,需要将Entra ID的角色转换为带ROLE_前缀的权限,添加以下配置类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@Configuration
public class SecurityConfig {

    @Bean
    public JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter();
        authoritiesConverter.setAuthorityPrefix("ROLE_"); // 添加ROLE_前缀
        authoritiesConverter.setAuthoritiesClaimName("roles"); // 指定从roles声明提取角色

        JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
        converter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
        return converter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .oauth2ResourceServer(oauth2 -> oauth2
                        .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter()))
                );
        return http.build();
    }
}

配置完成后,即可将@PreAuthorize改回:

@PreAuthorize("hasRole('Admin')")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 06:45:20