问题
在 Spring Security 6 和 Spring Boot 3 中,如何使用 Java 配置删除 ROLE_
前缀?
我有一个使用 Spring Security 6、Spring Boot 3 和 Thymeleaf 的项目。当我在 Thymeleaf 页面中显示用户的角色时,使用下面的代码
<span sec:authentication="principal.authorities"></span>
它返回:
[ROLE_SUPERVISOR]
我需要什么
我需要删除 ROLE_
前缀。我想使用 Java 配置在 Spring Security 配置中更改此设置。
当我在 Thymeleaf 页面中显示用户的角色时
<span sec:authentication="principal.authorities"></span>
我想让它显示
[SUPERVISOR]
我想删除 ROLE_
前缀。我想使用 Java 配置在 Spring Security 中更改此设置。
我的环境
- Spring安全6.0.3
- Spring Boot 3.0.6
- 百里香叶3.1.1
- Java 17.0.7
进行的研究
基于Spring Security 6 documentation ,它说我可以创建一个新的 GrantedAuthorityDefaults
bean 来删除角色前缀,例如:
@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("");
}
我尝试过这个,但不起作用。即使重新启动 Spring Boot 应用程序后,它仍然在 Thymeleaf 页面中显示角色的 ROLE_ 前缀。
我也搜索 stackoveflow。我找到了下面列出的 stackoverflow 帖子。但他们没有工作。它们适用于以前版本的 Spring Security 5。我需要适用于 Spring Security 6 和 Spring Boot 3 的解决方案。
How do I remove the ROLE_ prefix from Spring Security with JavaConfig?
Spring security @Secured always need ROLE_ prefix, how we can remove the prefix
如何重现
我有一个使用 Spring Security 6 和 Spring Boot 3 的小型 Spring MVC 应用程序。
1。我的 Spring Security 配置
文件 - SecurityRules.java
package com.testspring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.provisioning.UserDetailsManager;
@Configuration
public class SecurityRules {
@Bean
public UserDetailsManager users() {
UserDetails scott = User.builder().username("scott").password("{noop}tiger")
.roles("SUPERVISOR").build();
return new InMemoryUserDetailsManager(scott);
}
}
2。我的 Controller 代码
文件 - TestController.java
package com.testspring;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class TestController {
@RequestMapping("/")
public String indexView() {
return "index";
}
}
3。我的 Thymeleaf 页面
文件-index.html
<!DOCTYPE html>
<html lang="en" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<body>
<span sec:authentication="principal.authorities"></span>
</body></html>
4。我的 Spring Boot 应用程序
文件 - TestSpringApplication.java
package com.testspring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestSpringApplication {
public static void main(String[] args) {
SpringApplication.run(TestSpringApplication.class, args);
}
}
5。我的 Maven 配置文件
文件 - pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.testspring</groupId>
<artifactId>testspring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>testspring</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
6。运行代码
运行Spring Boot应用程序时,可以查看http://localhost:8080。使用登录名 Scott/tiger
。页面显示用户角色。
最佳答案
侵入性最小的解决方案:
UserDetails scott = User.builder().username("scott").password("{noop}tiger")
.authorities("SUPERVISOR"/*, ...*/).build();
使用authorities(...)
而不是roles(...)
。 (根据我轻描淡写的说法,这个(前缀)是这些“术语”之间的唯一区别......但却是困惑和复杂性的“永恒”根源)
@Bean static GrantedAuthorityDefaults
似乎相当负责“评估”(hasRole/hasAuthority ?)。 (与用户详细信息服务不同:它“管理”/分配...)
启发: Difference between Role and GrantedAuthority in Spring Security
关于spring - 如何删除Spring Security 6和Spring Boot 3中的ROLE_前缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76231891/