我正在编写一个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注册吗?在网上找不到任何文章。
建议和帮助深表感谢。
更新:
为什么csrf().disable()
有效
CSRF代表跨站点请求伪造
简而言之,它是与请求一起发送以防止攻击的令牌。为了使用Spring Security的CSRF保护,我们首先需要确保我们使用正确的HTTP方法任何修改状态(PATCH
,POST
,PUT
,和DELETE
-不是GET
)。
使用Spring CookieCsrfTokenRepository进行CSRF保护的工作方式如下:
Set-cookie
包含安全生成的XSRF令牌的标头该方法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)
您可以在这里找到最小的工作示例
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] 删除。
我来说两句