@PreAuthorize
注解在 Spring Security 中提供了一种声明式的方法,可以在您的 Spring Boot 应用中添加方法级别的安全检查。本教程将引导您设置并有效使用 @PreAuthorize
,确保用户只能在具有特定角色或权限的情况下调用 REST API。
什么是 @PreAuthorize?
@PreAuthorize
是 Spring Security 的一个注解,用于指定在方法调用前应评估的表达式,以确定调用者是否有权执行该方法。
将 Spring Security 添加到项目中
确保您的项目中包含 Spring Security。对于 Maven,将以下依赖项添加到 pom.xml
文件中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
对于 Gradle,将以下内容添加到 build.gradle
文件中:
implementation 'org.springframework.boot:spring-boot-starter-security'
启用方法级安全
要在 Spring Boot 应用的 Rest Controller 类中对特定方法应用 Spring Security,必须启用方法级安全。为此,您需要使用 @EnableMethodSecurity
注解。
@Configuration
@EnableMethodSecurity
public class SpringSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(HttpMethod.GET, "/api/user").hasRole("USER")
.requestMatchers(HttpMethod.GET, "/api/admin").hasRole("ADMIN")
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails ramesh = User.builder()
.username("ramesh")
.password(passwordEncoder().encode("password"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(ramesh, admin);
}
}
@EnableMethodSecurity
是一个 Spring 注解,用于在 Spring 应用中启用方法级安全。使用此注解后,Spring 将为包含安全方法的类创建代理,并在调用这些方法时拦截以检查调用者是否具有执行方法所需的权限。
此注解与其他注解(如 @PreAuthorize
、@PostAuthorize
、@Secured
和 @RolesAllowed
)一起工作,这些注解用于指定方法的访问控制规则。例如,您可以使用 @PreAuthorize
指定只有具有特定角色或权限的用户才能调用某个方法;或者使用 @PostAuthorize
指定方法只返回调用者有权查看的数据。
使用 @PreAuthorize 注解保护 REST API
以下代码展示了如何使用 Spring Security 进行基于角色的 RESTful 端点授权。
@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')")
: 应用于helloAdmin()
方法,表示只有具有 ‘ADMIN’ 角色的用户才能访问此端点。@PreAuthorize("hasRole('USER')")
: 应用于helloUser()
方法,限制只有具有 ‘USER’ 角色的用户才能访问。
总结
本教程介绍了如何使用 Spring 方法级安全和 @PreAuthorize
注解来保护 RestController 方法。通过这些步骤,您可以确保只有具有适当角色或权限的用户才能访问特定的 REST API。