spring - 如何删除Spring Security 6和Spring Boot 3中的ROLE_前缀?

标签 spring spring-boot spring-mvc spring-security spring-thymeleaf

问题

在 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 的解决方案。

如何重现

我有一个使用 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/

相关文章:

java - 如何在 Spring XD 中向 "side channel"发送消息?

java - Spring-boot 中的 NullPointerException 如何修复它?

angular - 如何使用本地镜像路径以 Angular 显示图像

使用注释和全局拒绝的 Spring Security 白名单方法

java - 用户 token 认证 Spring MVC RESTful API

java - Spring AspectJ 集成不起作用

java - application.properties 中的注释

java - ExceptionHandler 调用但不影响 http 响应

java - 返回枚举名称和字符串值作为 api 响应

java - 将 .js、.css 文件提供给 html 模板时出现 spring-boot 404 错误