Spring Boot @RestController 拒绝 POST 请求
Spring Boot @RestController rejects a POST request
一个POST请求
http://localhost:9278/submitEnrollment
封装外部 SOAP 调用的 Spring 引导应用程序会导致以下结果:
{
"timestamp": 1439480941381,
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource",
"path": "/submitEnrollment"
}
这似乎不是正常行为,我想知道我需要 Spring 什么引导配置来 relax/disable 来阻止此客户端身份验证。
以下是相关的代码片段:
应用程序的配置(需要所有必要的管道来通过 SSL 发送安全的 SOAP 调用并且应该影响 Web 层):
@Configuration
@ComponentScan({"a.b.c.d", "com.submit.enrollment"})
@PropertySource("classpath:/submit-enrollment.properties")
public class SubmitEnrollmentConfig {
@Value("${marshaller.contextPaths}")
private String[] marshallerContextPaths;
@Value("${default.Uri}")
private String defaultUri;
@Bean
public FfmSoapClient connectivityClient() throws Throwable {
FfmSoapClient client = new FfmSoapClient();
client.setWebServiceTemplate(webServiceTemplate());
return client;
}
@Bean
public KeyStore keyStore() throws Throwable {
KeyStoreFactoryBean keyStoreFactory = new KeyStoreFactoryBean();
keyStoreFactory.setPassword("!zxy!36!");
keyStoreFactory.setLocation(new ClassPathResource("zxy.jks"));
keyStoreFactory.setType("jks");
keyStoreFactory.afterPropertiesSet();
return keyStoreFactory.getObject();
}
@Bean
public KeyManager[] keyManagers() throws Throwable{
KeyManagersFactoryBean keyManagerFactory = new KeyManagersFactoryBean();
keyManagerFactory.setKeyStore(keyStore());
keyManagerFactory.setPassword("!zxy!36!");
keyManagerFactory.afterPropertiesSet();
return keyManagerFactory.getObject();
}
@Bean
public HttpsUrlConnectionMessageSender httpsUrlSender() throws Throwable {
HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();
sender.setSslProtocol("TLS");
sender.setKeyManagers(keyManagers());
return sender;
}
@Bean
public WebServiceTemplate webServiceTemplate() throws Throwable {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setMarshaller(marshaller());
webServiceTemplate.setUnmarshaller(marshaller());
webServiceTemplate.setDefaultUri(defaultUri);
webServiceTemplate.setMessageFactory(messageFactory());
webServiceTemplate.setMessageSender(/*new HttpComponentsMessageSender()*/httpsUrlSender());
webServiceTemplate.setInterceptors(new ClientInterceptor[] { wss4jSecurityInterceptor(), new LogbackInterceptor() }); //order matters
webServiceTemplate.setMessageSender(httpsUrlSender());
return webServiceTemplate;
}
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPaths(marshallerContextPaths);
return marshaller;
}
@Bean
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
return messageFactory;
}
@Bean
public Wss4jSecurityInterceptor wss4jSecurityInterceptor() throws Throwable{
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions(/*"UsernameToken"*/WSHandlerConstants.USERNAME_TOKEN + " "+ WSHandlerConstants.TIMESTAMP);
//wss4jSecurityInterceptor.setSecurementActions("Signature");
wss4jSecurityInterceptor.setSecurementUsername("07.ZIP.NJ*.390.639");
wss4jSecurityInterceptor.setSecurementPassword("oLD@cDh$(dKnCM");
wss4jSecurityInterceptor.setSecurementPasswordType(/*"PasswordDigest"*/WSConstants.PW_DIGEST);
wss4jSecurityInterceptor.setSecurementEncryptionCrypto(crypto());
wss4jSecurityInterceptor.setSecurementEncryptionKeyIdentifier("DirectReference");
//wss4jSecurityInterceptor.setValidationActions("Signature");
//wss4jSecurityInterceptor.setValidationSignatureCrypto( crypto() );
wss4jSecurityInterceptor.setSecurementTimeToLive(300);
return wss4jSecurityInterceptor;
}
@Bean
public Crypto crypto() throws Throwable {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
cryptoFactoryBean.setKeyStoreLocation(new ClassPathResource("zipari.jks"));
cryptoFactoryBean.setKeyStorePassword("!zxy!36!");
cryptoFactoryBean.afterPropertiesSet();
Crypto crypto = cryptoFactoryBean.getObject();
System.out.println("created crypto store: "+ crypto);
return crypto;
}
@Configuration
static class DatabaseConfig {
@Bean @Lazy
DataSource dataSource() {
return null;
}
}
}
申请:
public static void main(String[] args) throws Throwable {
SpringApplication app = new SpringApplication(SubmitEnrollmentApplication.class);
//app.addListeners(new ApplicationPidFileWriter());
ApplicationContext ctx = app.run(args);
控制器:
@RestController
public class SubmitEnrollmentController {
private final Logger logger = LoggerFactory.getLogger(SubmitEnrollmentController.class);
//@Autowired @Qualifier("brokerService")private BrokerService service;
@RequestMapping(value = "/submitEnrollment", method = RequestMethod.POST, consumes="application/json")
public String submitEnrollment(@RequestBody String jsonIn){
logger.info("Received submit enrollment request: {}, start processing...", jsonIn);
您的问题是,您的其余端点已通过 spring 安全性验证。所以错误消息清楚地表明,您希望在发送请求之前对自己进行身份验证。您可以忽略身份验证,直到您确保一切正常。你需要的是这样的东西。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/submitEnrollment").permitAll().and().csrf().disable();
}
你可以从here. If you need more complex config, go through this jhipster project, and specifically this file找到一个好的配置。
主 Spring 配置文件的以下补充帮助我实现了我所需要的:
@Configuration
static class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/**");
}
}
一个POST请求
http://localhost:9278/submitEnrollment
封装外部 SOAP 调用的 Spring 引导应用程序会导致以下结果:
{
"timestamp": 1439480941381,
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource",
"path": "/submitEnrollment"
}
这似乎不是正常行为,我想知道我需要 Spring 什么引导配置来 relax/disable 来阻止此客户端身份验证。
以下是相关的代码片段:
应用程序的配置(需要所有必要的管道来通过 SSL 发送安全的 SOAP 调用并且应该影响 Web 层):
@Configuration
@ComponentScan({"a.b.c.d", "com.submit.enrollment"})
@PropertySource("classpath:/submit-enrollment.properties")
public class SubmitEnrollmentConfig {
@Value("${marshaller.contextPaths}")
private String[] marshallerContextPaths;
@Value("${default.Uri}")
private String defaultUri;
@Bean
public FfmSoapClient connectivityClient() throws Throwable {
FfmSoapClient client = new FfmSoapClient();
client.setWebServiceTemplate(webServiceTemplate());
return client;
}
@Bean
public KeyStore keyStore() throws Throwable {
KeyStoreFactoryBean keyStoreFactory = new KeyStoreFactoryBean();
keyStoreFactory.setPassword("!zxy!36!");
keyStoreFactory.setLocation(new ClassPathResource("zxy.jks"));
keyStoreFactory.setType("jks");
keyStoreFactory.afterPropertiesSet();
return keyStoreFactory.getObject();
}
@Bean
public KeyManager[] keyManagers() throws Throwable{
KeyManagersFactoryBean keyManagerFactory = new KeyManagersFactoryBean();
keyManagerFactory.setKeyStore(keyStore());
keyManagerFactory.setPassword("!zxy!36!");
keyManagerFactory.afterPropertiesSet();
return keyManagerFactory.getObject();
}
@Bean
public HttpsUrlConnectionMessageSender httpsUrlSender() throws Throwable {
HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();
sender.setSslProtocol("TLS");
sender.setKeyManagers(keyManagers());
return sender;
}
@Bean
public WebServiceTemplate webServiceTemplate() throws Throwable {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setMarshaller(marshaller());
webServiceTemplate.setUnmarshaller(marshaller());
webServiceTemplate.setDefaultUri(defaultUri);
webServiceTemplate.setMessageFactory(messageFactory());
webServiceTemplate.setMessageSender(/*new HttpComponentsMessageSender()*/httpsUrlSender());
webServiceTemplate.setInterceptors(new ClientInterceptor[] { wss4jSecurityInterceptor(), new LogbackInterceptor() }); //order matters
webServiceTemplate.setMessageSender(httpsUrlSender());
return webServiceTemplate;
}
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPaths(marshallerContextPaths);
return marshaller;
}
@Bean
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
return messageFactory;
}
@Bean
public Wss4jSecurityInterceptor wss4jSecurityInterceptor() throws Throwable{
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions(/*"UsernameToken"*/WSHandlerConstants.USERNAME_TOKEN + " "+ WSHandlerConstants.TIMESTAMP);
//wss4jSecurityInterceptor.setSecurementActions("Signature");
wss4jSecurityInterceptor.setSecurementUsername("07.ZIP.NJ*.390.639");
wss4jSecurityInterceptor.setSecurementPassword("oLD@cDh$(dKnCM");
wss4jSecurityInterceptor.setSecurementPasswordType(/*"PasswordDigest"*/WSConstants.PW_DIGEST);
wss4jSecurityInterceptor.setSecurementEncryptionCrypto(crypto());
wss4jSecurityInterceptor.setSecurementEncryptionKeyIdentifier("DirectReference");
//wss4jSecurityInterceptor.setValidationActions("Signature");
//wss4jSecurityInterceptor.setValidationSignatureCrypto( crypto() );
wss4jSecurityInterceptor.setSecurementTimeToLive(300);
return wss4jSecurityInterceptor;
}
@Bean
public Crypto crypto() throws Throwable {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
cryptoFactoryBean.setKeyStoreLocation(new ClassPathResource("zipari.jks"));
cryptoFactoryBean.setKeyStorePassword("!zxy!36!");
cryptoFactoryBean.afterPropertiesSet();
Crypto crypto = cryptoFactoryBean.getObject();
System.out.println("created crypto store: "+ crypto);
return crypto;
}
@Configuration
static class DatabaseConfig {
@Bean @Lazy
DataSource dataSource() {
return null;
}
}
}
申请:
public static void main(String[] args) throws Throwable {
SpringApplication app = new SpringApplication(SubmitEnrollmentApplication.class);
//app.addListeners(new ApplicationPidFileWriter());
ApplicationContext ctx = app.run(args);
控制器:
@RestController
public class SubmitEnrollmentController {
private final Logger logger = LoggerFactory.getLogger(SubmitEnrollmentController.class);
//@Autowired @Qualifier("brokerService")private BrokerService service;
@RequestMapping(value = "/submitEnrollment", method = RequestMethod.POST, consumes="application/json")
public String submitEnrollment(@RequestBody String jsonIn){
logger.info("Received submit enrollment request: {}, start processing...", jsonIn);
您的问题是,您的其余端点已通过 spring 安全性验证。所以错误消息清楚地表明,您希望在发送请求之前对自己进行身份验证。您可以忽略身份验证,直到您确保一切正常。你需要的是这样的东西。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/submitEnrollment").permitAll().and().csrf().disable();
}
你可以从here. If you need more complex config, go through this jhipster project, and specifically this file找到一个好的配置。
主 Spring 配置文件的以下补充帮助我实现了我所需要的:
@Configuration
static class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/**");
}
}