Ron*_*dey 30 java eclipse backend spring-security spring-boot
当我尝试运行应用程序时,它无法启动并抛出此异常。
该方法无法判断这些模式是否是 Spring MVC 模式。如果此端点是 Spring MVC 端点,请使用 requestMatchers(MvcRequestMatcher); 否则,请使用 requestMatchers(AntPathRequestMatcher)。
我是 Spring Security 的新手。请帮我解决这个错误。
这是我的 spring 安全配置类
package com.ronit.SpringSecurityTutorial.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity
@Configuration
public class SecurityConfiguration {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
AuthenticationManager authManager(UserDetailsService detailsService) {
DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider();
daoProvider.setUserDetailsService(detailsService);
return new ProviderManager(daoProvider);
}
@SuppressWarnings("removal")
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.csrf(csrf -> csrf.disable()).authorizeHttpRequests(auth -> {
auth.anyRequest().authenticated();
auth.requestMatchers("/auth/**").permitAll();
auth.anyRequest().authenticated();
}).httpBasic().and().build();
}
}
Run Code Online (Sandbox Code Playgroud)
这是 Spring Boot 应用程序
package com.ronit.SpringSecurityTutorial;
import java.util.HashSet;
import java.util.Set;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.ronit.SpringSecurityTutorial.models.ApplicationUser;
import com.ronit.SpringSecurityTutorial.models.Role;
import com.ronit.SpringSecurityTutorial.repository.RoleRepository;
import com.ronit.SpringSecurityTutorial.repository.UserRepository;
@SpringBootApplication
public class SpringSecurityTutorialApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityTutorialApplication.class,args);
}
@Bean
CommandLineRunner run(RoleRepository roleRepository, UserRepository userRepository,
PasswordEncoder passwordEncoder) {
return args -> {
if (roleRepository.findByAuthority("ADMIN").isPresent())
return;
Role adminRole = roleRepository.save(new Role("ADMIN"));
roleRepository.save(new Role("USER"));
Set<Role> roles = new HashSet<>();
roles.add(adminRole);
ApplicationUser admin = new
ApplicationUser(1, "Admin", passwordEncoder.encode("Password"), roles);
userRepository.save(admin);
};
}
}
Run Code Online (Sandbox Code Playgroud)
这些是 pom.xml 中的依赖项
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<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-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)
application.properties 文件中没有与安全相关的配置。
我在 Google 上搜索了这个并找到了一些 Stack Overflow 页面,但没有一个使用与我的配置类似的配置。
我看了一个在线教程并做了这个。我正确地执行了每个步骤,但我的配置不起作用。
该应用程序立即停止并终止。
我在我的应用程序中使用 Spring Boot 3 和 Spring Security 6。
小智 29
由于漏洞CVE-2023-34035而发生迁移。
如果您收到如下错误:
该方法无法判断这些模式是否是 Spring MVC 模式。如果此端点是 Spring MVC 端点,请使用
requestMatchers(MvcRequestMatcher)
; 否则,请使用requestMatchers(AntPathRequestMatcher)
.
您应该使用完整的 RequestMatcher。
例如,如果应用程序将 Servlet 部署到 /my-servlet/* 并授权该流量,如下所示:
@Bean
SecurityFilterChain appSecurity(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/my-servlet/**").hasRole("USER")
.requestMatchers("/spring-mvc-controller/**").hasRole("USER")
.anyRequest().authenticated()
)
// ...
return http.build();
}
Run Code Online (Sandbox Code Playgroud)
那么,应用程序应该执行以下操作:
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
@Bean
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
return new MvcRequestMatcher.Builder(introspector);
}
@Bean
SecurityFilterChain appSecurity(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers(antMatcher("/my-servlet/*")).hasRole("USER")
.requestMatchers(mvc.pattern("/spring-mvc-controller/**")).hasRole("USER")
.anyRequest().authenticated()
)
// ...
return http.build();
}
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请阅读 Spring 提供的存储库:cve-2023-34035-mitigations
Rag*_*ghu 14
目前,https://spring.io/security/cve-2023-34035推荐了两个选项
第一个选项:
在 tomcat 中做了一个非常简单的小型 poc war Web 应用程序。调试了这个方法 -
org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.requestMatchers(HttpMethod方法,字符串...模式)
研究了https://spring.io/security/cve-2023-34035
就在上述方法中的以下几行之前,我检查了注册对象中的内容。
Assert.isTrue(registrations.size() == 1, "此方法无法判断这些模式是否是 Spring MVC 模式。如果此端点是 Spring MVC 端点,请使用 requestMatchers(MvcRequestMatcher);否则,请使用 requestMatchers( AntPathRequestMatcher).");
发现它是注册的
org.apache.catalina.servlets.DefaultServlet against "default"
org.apache.jasper.servlet.JspServlet against "jsp"
org.springframework.web.servlet.DispatcherServlet against "dispatcher"
Run Code Online (Sandbox Code Playgroud)
在https://spring.io/security/cve-2023-34035中,他们提到“有时不需要这些额外的 servlet。例如,某些 servlet 容器会添加 DispatcherServlet 有效替换的 DefaultServlet。在许多情况下,这样的 servlet 可以从容器的全局配置中删除”。
他们的意思是我们应该编辑 apache-tomcat-10.1.10\conf\web.xml。
我们应该注释掉 web.xml 中 org.apache.catalina.servlets.DefaultServlet、org.apache.jasper.servlet.JspServlet 的注册。我们还应该删除同一 web.xml 中的映射条目
对于其他 servlet 容器,我们可以考虑类似的概念。
第二个选项:
另一个选项是执行他们在“有关缓解示例,请参阅以下 Spring Security 示例应用程序和相应的差异”中建议的操作。https://spring.io/security/cve-2023-34035即遵循https://github.com/spring-projects/spring-security-samples/commit/4e3bec904a5467db28ea33e25ac9d90524b53d66
换句话说,他们给出的例子是 Replace :
.requestMatchers("/login", "/resources/**").permitAll()
Run Code Online (Sandbox Code Playgroud)
和
.requestMatchers(mvc.pattern("/login"),
mvc.pattern("/resources/**")).permitAll()
Run Code Online (Sandbox Code Playgroud)
在 Web 应用程序中,您通常会使用 MVC 匹配器,如下所示。您还可以使用 ant 匹配器 - 使用 ant 匹配器有一点风险,如此处所述 - antMatcher 和 mvcMatcher 之间的差异。最好避免使用 ant matcher,除非您愿意在开始使用它时进行必要的测试。在复杂的场景中也可以使用正则表达式匹配器 - 仅在需要时使用它(不是在您只想解决当前问题的场景中)。
关于如何实现 mvc.pattern() 本身,这里是步骤。在某处声明一个 bean,如下所示。
@Bean
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
return new MvcRequestMatcher.Builder(introspector);
}
Run Code Online (Sandbox Code Playgroud)
在您的安全配置中,只需像这样自动装配它:
@Autowired
MvcRequestMatcher.Builder mvc;
Run Code Online (Sandbox Code Playgroud)
决策点:
如果您想保留原始代码,请尝试编辑服务器的(不是项目的)web.xml - 或类似的配置(如果不是 tomcat) - 而是其他一些 servlet 容器,以消除 servlet 容器中默认出现的额外 servlet。
如果您愿意更改代码,请尝试第二个选项。
另请注意:
有时,如果它的遗留代码并且您在代码中使用 DispatcherServlet 方法,您将必须消除它以使用第一个选项,否则就选择第二个选项。
希望这可以帮助
添加更多新信息:
事实上,如果您进一步从 spring-boot-starter-parent:3.1.2 迁移到 spring-boot-starter-parent:3.1.3,则消息会更加清晰。它说明了问题:您的 servlet 上下文中有多个可映射 servlet:{org.apache.jasper.servlet.JspServlet=[*.jspx, *.jsp], org.springframework.web.servlet.DispatcherServlet=[/ ]}。
这就是为什么遵循https://spring.io/security/cve-2023-34035 的一个选项是禁用默认和 jsp 相关的 servlet。如果您不想更改代码但可以更改服务器配置,则很有用。
如果您选择代码更改路线,则第二个选项始终会清晰地记录下来。“对于每个 MvcRequestMatcher,调用 MvcRequestMatcher#setServletPath 来指示 servlet 路径。” 只有“否则”他们才会提到 AntMatchers
我将重复避免使用 AntMatcher,因为如果您选择第二个选项,则使用 Web 应用程序进行此迁移时会存在危险。
归档时间: |
|
查看次数: |
26580 次 |
最近记录: |