我面临一个无法解决的问题,我的弹簧配置知识很差:每个GET返回错误404,每个POST返回错误405 。 我的spring安全过滤器运行良好,但@PostMapping或@GetMapping注释方法都没有被调用。 我已经注意将旧属性 server.context-path 重命名为新名称 server.servlet.context-path ,但它仍然无法正常工作。 我使用了网络服务器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<version>${springBoot.version}</version>
</dependency>
我的app.properties文件名为application.mssql.properties:
## Hibernate properties
... some properties ...
##Spring boot properties
server.servlet.context-path =/my-context
此服务器实例配置位于我的ApplicationConfiguration:
@SpringBootApplication(scanBasePackages = {
"t.i.DAO",
"t.i.SERVICES",
"t.i.config",
"t.i.config.security" })
@PropertySource({ "classpath:application.mssql.properties" })
@EnableCaching
@EnableTransactionManagement
public class ApplicationConfiguration {
// Properties of application.mssql.properties file
@Autowired
private Environment env;
... some code there...
@Bean
public ConfigurableServletWebServerFactory undertowServerInstance() {
UndertowServletWebServerFactory customizer = new UndertowServletWebServerFactory();
customizer.addBuilderCustomizers((builder) -> {
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
});
// EDIT: add: set the context by reading app.properties
customizer.setContextPath(env.getProperty("server.servlet.context-path"));
return customizer;
}
}
请注意,使用我的旧spring 1.5配置,方法undertowServerInstance()是不同的:
@Bean
public EmbeddedServletContainerCustomizer undertowServerInstance() {
return (container) -> {
if(container instanceof UndertowEmbeddedServletContainerFactory) {
((UndertowEmbeddedServletContainerFactory) container)
.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
}
};
}
我使用Spring安全配置类SecurityConfig,如下所示:
包t.i.config;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) // allows AOP @PreAuthorize and some other annotations to be applied to methods.
@EnableWebSecurity
@EnableScheduling // allows to run Spring schedulers and periodically run some tasks. We use scheduler for evicting EhCache tokens.
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
... some code for security configuration ...
// adding authentication filter
http.addFilterBefore(new AuthenticationFilter(this.authenticationManager), BasicAuthenticationFilter.class);
}
}
此类用于从用户凭据生成新令牌或检查令牌有效性(如果它存在于标头上)(每个请求都会调用此过滤器并且它仍然有效):
package t.i.config.security;
public class AuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
// check or create token. Exception if credentials or token invalid
}
catch(AuthenticationException authenticationException){
((HttpServletResponse) http).sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
return;
}
chain.doFilter(request, response);
}
}
这是我的WebMvcConfig,其中包含@RestController类包位置(编辑:添加实现WebMvcConfigurer ):
package t.i.config;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"t.i.controllers"})
public class WebMvcConfig implements WebMvcConfigurer {
... code there ...
}
例如,当我调用/api/authenticate
URL时,会调用我的spring身份验证过滤器方法并创建令牌,但从不调用此WS(而是返回405):
package t.i.controllers;
@RestController
public class AuthenticationController {
@PostMapping("api/authenticate")
public UserDTO authenticate(AuthenticationWithToken principal) {
... some code there that is never called with spring boot 2.0 ...
return userDTO;
}
}
我仍然不明白这个问题,我认为Undertow配置中缺少某些东西。
编辑:在ApplicationConfiguration.undertowServerInstance()
方法中,如果我删除该行:
// EDIT: add: set the context by reading app.properties
customizer.setContextPath(env.getProperty("server.servlet.context-path"));
然后不再触发AuthenticationFilter。使用spring boot 1.5,我从不需要明确指定Undertow上下文。
编辑:我将我的身份验证WS方法更改为GET:
package t.i.CONTROLLERS;
@RestController
public class AuthenticationController {
@RequestMapping(value = "/api/authenticate", method = RequestMethod.GET)
public UserDTO authenticate(AuthenticationWithToken principal) {
... some code there that is still never called with spring boot 2.0 ...
return userDTO;
}
}
身份验证过滤器运行良好,但仍未调用方法AuthenticationController.authenticate
。这是我用chrome调试器得到的:
总结:
答案 0 :(得分:0)
您的方法已映射到POST
请求,405表示不允许使用方法。
那是因为你发送了我认为的GET请求。
将映射更改为@GetMapping("api/authenticate")
或使用Postman之类的工具发送POST请求。
我会推荐Postman方法,因为做一些像auth wuth POST
请求这样的事情是个好主意。
答案 1 :(得分:0)
Spring Boot正在使用WebMvcConfigurationSupport
表示它不应该自动配置Spring MVC。请尝试将extends WebMvcConfigurationSupport
替换为implements WebMvcConfigurer
。