Spring安全配置不适用于Spring SimpleUrlHandlerMapping

Kousick Shanmugam Nagaraj:

我正在编写一个Spring Boot应用程序,其中通过SimpleUrlHandlerMapping配置将URL注册到Bean。为什么我不使用@Controller或@RequestMapping类来做到这一点?因为我想在运行时动态注册URL。

我正在使用以下代码向控制器注册简单的URL

    @Bean
    public SimpleUrlHandlerMapping sampleServletMapping() {
        SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
        mapping.setOrder(Integer.MAX_VALUE - 2);

        Properties urlProperties = new Properties();
        urlProperties.put("/index", "myController");

        mapping.setMappings(urlProperties);

        return mapping;
    }

上面的代码工作正常,我能够命中名为“ myController”的控制器Bean。

当我使用Spring Security时出现问题。我介绍了spring安全性并配置了InMemoryAuthentication,并按如下所示设置我的配置。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/index").permitAll()
                .anyRequest()
                .permitAll();
    }

执行完此操作后,当我尝试访问/ index路径时,将引发403(禁止)错误。我已经尝试了allowAll()和fullyAuthenticated()配置。它似乎不起作用。但是,任何在@Controller和@RequestMapping注释中注册的Controller类都可以与Security完美配合。

因此,我的假设是Spring Security无法通过SimpleUrlHandlerMapping知道动态注册的URL。

我该如何解决?有什么办法可以告诉Spring Security包括我的动态URL注册吗?在网上找不到任何文章。

建议和帮助深表感谢。

帕特尔·罗米尔(Patel Romil):

更新:

为什么csrf().disable()有效

CSRF代表跨站点请求伪造

简而言之,它是与请求一起发送以防止攻击的令牌。为了使用Spring Security的CSRF保护,我们首先需要确保我们使用正确的HTTP方法任何修改状态(PATCHPOSTPUT,和DELETE-不是GET)。

使用Spring CookieCsrfTokenRepository进行CSRF保护的工作方式如下:

  1. 客户端向服务器(Spring Boot Backend)发出GET请求,例如对主页的请求
  2. Spring发送GET请求的响应以及Set-cookie包含安全生成的XSRF令牌的标头
  3. 浏览器使用XSRF令牌设置cookie
  4. 在发送状态更改请求(例如POST)时,客户端(可能是有角度的)将cookie值复制到HTTP请求标头中
  5. 该请求与标头和cookie一起发送(浏览器自动附加cookie)
  6. Spring比较标头和cookie值,如果相同,则接受请求,否则,将403返回给客户端

该方法withHttpOnlyFalse允许Angular读取XSRF cookie。确保Angular发出XHR请求并将其withCreddentials标志设置为true。

有关更多详细信息,您可以探索以下内容

更新方法 configure(HttpSecurity http)

 http
            .csrf()
            .ignoringAntMatchers("endpoint-to-be-ignored-for-csrf")
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .authorizeRequests()
            .antMatchers("/index").permitAll() 
            .anyRequest().authenticated();

antMatchers中使用allowAll()指定的端点不需要身份验证,并且antMatchers("/index").permitAll()可以正常工作。

  • 确保您的安全配置类使用@EnableWebSecurity注释@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
  • 安全配置类位于包结构中,并由Spring扫描。弹簧成分扫描

您可以在这里找到最小的工作示例


SecurityConfiguration.java

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // https://stackoverflow.com/a/56389047/10961238 -> WebSecurity vs HttpSecurity

    // Add this method if .antMatchers("/index").permitAll() does not work
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.debug(true);
//        web
//            .ignoring()
//            .antMatchers("/index");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/index").permitAll() //commenting this line will be results in 403
            .anyRequest().authenticated();
    }

}

SampleController.java

import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller("myController")
public class SampleController extends AbstractController {
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("::::::::::::::::::::::::::::::::Controller:::::::::::::::::::::::::::::::::");
        response.getWriter().print("Hello world!");
        return null;
    }
}

MainApplication.java

import com.example.mappings.controller.SampleController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;

import java.util.Properties;

@SpringBootApplication
public class MappingsApplication {

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

    @Bean
    public SimpleUrlHandlerMapping sampleServletMapping() {
        System.out.println("::::::::::::::::::::::::::::::::SimpleUrlHandlerMapping:::::::::::::::::::::::::::::::::");
        SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
        mapping.setOrder(Integer.MAX_VALUE - 2);

        Properties urlProperties = new Properties();
        urlProperties.put("/index", sampleController());
        mapping.setMappings(urlProperties);

        return mapping;
    }

    @Bean
    public SampleController sampleController() {
        System.out.println("::::::::::::::::::::::::::::::::Setting SampleController:::::::::::::::::::::::::::::::::");
        return new SampleController();
    }
}

application.properties

spring.security.user.name = user
spring.security.user.password = user
spring.security.user.roles = ADMIN

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

SimpleUrlHandlerMapping的Java配置(春季启动)

Spring SimpleUrlHandlerMapping:模式与URL不匹配

@Autowired不适用于XML配置Spring

Spring Data JPA不适用于自动配置的entityManagerFactory

使用Spring Boot / Spring Security配置公共端点仅适用于GET,不适用于POST

Spring“cacheNames”不适用于“key”

@PostFilter不适用于Spring @Aspect

RedirectAttributes不适用于Spring 5

Spring表格不适用于jsp

SessionAttributes不适用于Spring Boot

JsonIgnoreProperties不适用于Spring Boot

AngularJS模板不适用于Spring

spring.profiles.include 不适用于 spring 云配置服务器?

Spring Boot自动重新配置不适用于spring-boot-data-starter-jdbc

Spring Boot安全性不适用于Google App Engine

Spring Security注销不适用于Spring 4 CORS

AWS实例配置文件不适用于Spring Cloud AWS

Spring Boot Cloud Kubernetes配置不适用于多个Pod

Prometheus配置不适用于Spring Boot 2.3.0:ClassNotFoundException:io.micrometer.prometheus.HistogramFlavor

如何在SpringBoot中使用SimpleUrlHandlerMapping

直接用户消息不适用于 Spring Websocket

Spring依赖注入不适用于继承

代理设置不适用于Spring WebClient

Spring Transactional方法不适用于单独的线程

Autowired为空,不适用于Jersey + Spring

Spring Data Rest 投影不适用于单个资源

AspectJ LTW(编织)不适用于Spring Boot

Spring Boot @Autowired by General不适用于@InjectMocks

Spring Security jdbcAuthentication不适用于默认角色处理