Spring-boot jersey : resources not autodiscover - java

I try to use Spring-boot with jetty and jersey.
No problem with the jetty part. I can start server and spring resources are running (trace, metrics,info,beans,....) but my resources didn't run.
My configuration files are :
Launcher.java
#Configuration
#PropertySource("classpath:application.properties")
#EnableAutoConfiguration
#ComponentScan(basePackages = {"com.fdilogbox.report.serveur"})
public class Launcher extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Launcher.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Launcher.class);
}
#Bean
public ServletRegistrationBean jerseyServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), "/api/*");
registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, ResourcesConfiguration.class.getName());
return registration;
}
#Bean
public EmbeddedServletContainerFactory containerFactory() {
final JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory = new JettyEmbeddedServletContainerFactory() {
#Override
protected JettyEmbeddedServletContainer getJettyEmbeddedServletContainer(Server server) {
return new JettyEmbeddedServletContainer(server);
}
};
jettyEmbeddedServletContainerFactory.addServerCustomizers(new JettyConfiguration());
return jettyEmbeddedServletContainerFactory;
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
JettyConfiguration.java
public class JettyConfiguration implements JettyServerCustomizer {
#Override
public void customize(Server server) {
WebAppContext webAppContext = (WebAppContext) server.getHandler();
try {
// Load configuration from resource file (standard Jetty xml configuration) and configure the context.
createConfiguration("/jetty.xml").configure(webAppContext);
createConfiguration("/jetty-rewrite.xml").configure(server);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private XmlConfiguration createConfiguration(String xml) throws IOException, SAXException {
return new XmlConfiguration(Launcher.class.getResourceAsStream(xml));
}
}
ResourcesConfiguration.java
public class ResourcesConfiguration extends ResourceConfig {
public ResourcesConfiguration() {
super();
PackageNamesScanner resourceFinder = new PackageNamesScanner(new String[]{"com.fdilogbox.report.serveur.business.resources"}, true);
registerFinder(resourceFinder);
register(JacksonFeature.class);
}
}
and my resources file :
#Path("builder")
#Component
public class ReportBuilderResource {
#Autowired
private ReportBuilderService reportBuilderService;
#GET
#Path("list")
#Produces(MediaType.APPLICATION_JSON)
public String[] findAll() {
return reportBuilderService.findAllReport();
}
}
If I try to acces "localhost:9090/api/builder/list" I get an 404 error.
But if I try "localhost:9090/bean" I get all bean on JSon format.
I think I have an error in my conf but I don't know where.

I found my mistake : management port is 9090 but the normal resources port is 8090.

Related

Using tls with jwt

I want to use tls with my sharing of token and login process. I implemented it and it works fine. I create a new port for tls that is https://localhost:8443 but there is a security leak in my app. When i post https://localhost:8443/login and take the jwt and use it with GET https://localhost:8443/welcome everything great if i use http instead of https bad request is returned. But if i change my url with http://localhost:8080/welcome and gives the token that is taken before the app must return bad request but it returns succesful open. My server and security config is below. What am i doing wrong?
Server Config:
#Configuration
public class ServerConfig {
#Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
#Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(getHttpConnector());
return tomcat;
}
private Connector getHttpConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
}
Security Config:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private JwtTokenFilter jwtTokenFilter;
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public void configurePasswordEncoder(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(userDetailsService).passwordEncoder(getBCryptPasswordEncoder());
}
#Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager getAuthenticationManager() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Auth Controller:
#RestController
#RequestMapping("/login")
public class AuthConroller {
#Autowired
private TokenManager tokenManager;
#Autowired
private AuthenticationManager authenticationManager;
#PostMapping
public ResponseEntity<String> login(#RequestBody LoginRequest loginRequest) {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
return ResponseEntity.ok(tokenManager.generateToken(loginRequest.getUsername()));
} catch (Exception e) {
throw e;
}
}
}
Message Controller:
#RestController
#RequestMapping("/message")
public class MessageController {
#GetMapping
public ResponseEntity<String> getMessage() {
return ResponseEntity.ok("JWT demo");
}
}

Could not handle mustUnderstand headers: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security. Returning fault

I went through links like: SOAPFaultException "MustUnderstand headers (oasis-200401-wss-wssecurity-secext-1.0.xsd) are not understood", but still struggling.
I'm using Spring Boot v2.2.2..RELEASE and SOAP project.
I am loading two different WSDL file into my project. One URL Generates to http://localhost:8080/employee/employee-soap which works fine. But http://localhost:8080/student/student-soap this gives below error.
2020-02-17 15:31:00.241 WARN 20236 --- [nio-8080-exec-5] o.s.w.soap.server.SoapMessageDispatcher : Could not handle mustUnderstand headers: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security. Returning fault
JavaCode:
#EnableWs
#Configuration
public class AppConfig extends WsConfigurerAdapter {
#SuppressWarnings({ "rawtypes", "unchecked" })
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/*");
}
#Bean
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.setSoapVersion(SoapVersion.SOAP_11);
messageFactory.afterPropertiesSet();
return messageFactory;
}
#Bean("empXSD")
public XsdSchema organizationSchema() {
return new SimpleXsdSchema(new ClassPathResource("/xsd/employee.xsd"));
}
#Bean(name = "employee")
public DefaultWsdl11Definition defaultWsdl11Definition(#Qualifier("empXSD") XsdSchema schema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("employee");
wsdl11Definition.setLocationUri("employee/employee-soap");
wsdl11Definition.setTargetNamespace("urn:example.com:dms:wsdls:employee");
wsdl11Definition.setSchema(schema);
wsdl11Definition.setCreateSoap11Binding(true);
return wsdl11Definition;
}
#Bean
#Qualifier(value="stuXSD")
public XsdSchema stuSchema() {
return new SimpleXsdSchema(new ClassPathResource("/xsd/student.xsd"));
}
#Bean(name = "student")
public DefaultWsdl11Definition geographyWsdl11Definition(#Qualifier("stuXSD") XsdSchema schema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("student");
wsdl11Definition.setLocationUri("student-soap");
wsdl11Definition.setTargetNamespace("urn:example.com:dms:wsdls:student");
wsdl11Definition.setSchema(schema);
wsdl11Definition.setCreateSoap11Binding(true);
return wsdl11Definition;
}
#Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(new Interceptor(endpoints, req));
}
}
Code:
#Configuration
public class SimpleMustUnderstandEndpointInterceptor implements SoapEndpointInterceptor{
private final String SAMPLE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
#Override
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
return true;
}
#Override
public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
return true;
}
#Override
public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
return true;
}
#Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
}
#Override
public boolean understands(SoapHeaderElement header) {
if(header.getName().getNamespaceURI().equalsIgnoreCase(SAMPLE_NS)) {
return true;
}
return false;
}
}
Per observation, looks like even this SoapEndpointInterceptor is not calling, before to that only its giving error.
During calling SOAP endpoint, below header information is going and its giving Fault as I mentioned above. Any pointers ?
<soapenv:Header><wsse:Security soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-wssecurity-utility-1.0.xsd"><wsse:UsernameToken wsu:Id="UsernameToken-
518482F2CDC2F635FF158202815227129"><wsse:Username>aispoc_usr1</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
username-token-profile-1.0#PasswordText">aispoc_usr1</wsse:Password><wsse:Nonce
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-
message-security-1.0#Base64Binary">/fdGCEilz/dkVeZE05b7LQ==</wsse:Nonce>
2020-02-18T12:15:52.271Z
You can try below config that would solve the issue.
#Bean
public Wss4jSecurityInterceptor securityInterceptor() {
Wss4jSecurityInterceptor security = new Wss4jSecurityInterceptor();
security.setValidationActions("NoSecurity");
security.setValidateRequest(false);
security.setValidateResponse(true);
return security;
}
#Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(securityInterceptor());
}
I was able to find the solution looking at https://docs.spring.io/spring-ws/site/apidocs/org/springframework/ws/soap/security/wss4j/Wss4jSecurityInterceptor.html and https://memorynotfound.com/spring-ws-username-password-authentication-wss4j/.
I simply used below bean and its started working fine.
#Bean
public Wss4jSecurityInterceptor securityInterceptor() {
Wss4jSecurityInterceptor security = new Wss4jSecurityInterceptor();
security.setSecurementActions("NoSecurity");
security.setSecurementPasswordType(WSConstants.PW_TEXT);
return security;
}

session events dont work in spring session

My app uses http and stomp over WebSocket. So i need to refresh my httpSession when user uses WebSockets So to not invent bicycles i decided to use Spring Session, as this provides clear integration between Http and WebSockets. But i was faced with a problem. When i used TOMCAT SESSION implementation i had this listener:
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addListener(new HttpSessionEventPublisher());
...
}
And it had worked just perfect. Session registry received a SessionDestroyEvent and destroyed a session.
Now, with Spring Session based on H2, it doesn't work.
I tried different approach like this:
#Bean
public HttpSessionEventPublisher httpSessionPublisher() {
return new HttpSessionEventPublisher();
}
#Bean
public HttpSessionListener httpSessionListener() {
return new HttpSessionListener() {
#Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("I EXIST");
}
#Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("I EXIST");
}
};
}
But it doesn't work too.
I use SpringSession with H2 storage, my config is:
#EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 15)
public class H2SessionConfig {
#Bean(name = "session_dataSource")
public EmbeddedDatabase dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("org/springframework/session/jdbc/schema-h2.sql").build();
}
#Bean
public PlatformTransactionManager transactionManager(#Qualifier("session_dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
#Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
#Bean
public HttpSessionListener httpSessionListener() {
return new HttpSessionListener() {
#Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("I EXIST");
}
#Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("I EXIST");
}
};
}
#Bean
public HttpSessionEventPublisher httpSessionPublisher() {
return new HttpSessionEventPublisher();
}
}
Thank you in advance.
Spring Session JDBC does not support publishing of session events due to obvious limitations of a RDBMS in that regard.
This limitation is documented both in reference manual and JdbcOperationsSessionRepository javadoc.

ERR Timed out after 1m0s: health check never passed

I am getting this exception after some 2-3 minutes of proper run of my app on cloud.I added timeout : 180 in manifest.yml file but the error still persists.
On STS console, I get the log as :
Execution failed for task ':cfPush'.> Application TestApp start timed out
Can anyone help me out in this please
Code:
#SpringBootApplication
public class SftpJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SftpJavaApplication.class)
.web(false)
.run(args);
}
#Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost("ip");
factory.setPort(port);
factory.setUser("user");
factory.setPassword("pwd");
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(factory);
}
#Bean
#Transformer(inputChannel = "stream",outputChannel="data")
public org.springframework.integration.transformer.Transformer transformer () {
return new org.springframework.integration.transformer.StreamTransformer("UTF-8");
}
#Bean
#InboundChannelAdapter(value = "stream", poller = #Poller(fixedDelay = "1000", maxMessagesPerPoll = "1"))
public MessageSource<InputStream> ftpMessageSource() {
SftpStreamingMessageSource messageSource = new SftpStreamingMessageSource(template(), null);
messageSource.setRemoteDirectory("/test1/test2/test3");
messageSource.setFilter(new SftpPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(),
"streaming"));
return messageSource;
}
#Bean
public SftpRemoteFileTemplate template() {
return new SftpRemoteFileTemplate(sftpSessionFactory());
}
#Bean
#ServiceActivator(inputChannel = "data" )
public MessageHandler handler() {
return new MessageHandler() {
#Override
public void handleMessage(Message<?> message) throws MessagingException {
System.out.println(">>>>>>>>>>>>>"+message.getPayload()); //instead of a print the message is published to rabbit mq
}
};
}
}
There is another class which connects to a rabbit mq service on cloud and consumes the message

How to disable ErrorPageFilter in Spring Boot?

I'm creating a SOAP service that should be running on Tomcat.
I'm using Spring Boot for my application, similar to:
#Configuration
#EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration.class)
public class AppConfig {
}
My webservice (example):
#Component
#WebService
public class MyWebservice {
#WebMethod
#WebResult
public String test() {
throw new MyException();
}
}
#WebFault
public class MyException extends Exception {
}
Problem:
Whenever I throw an exception within the webservice class, the following message is logged on the server:
ErrorPageFilter: Cannot forward to error page for request
[/services/MyWebservice] as the response has already been committed.
As a result, the response may have the wrong status code. If your
application is running on WebSphere Application Server you may be able
to resolve this problem by setting
com.ibm.ws.webcontainer.invokeFlushAfterService to false
Question:
How can I prevent this?
To disable the ErrorPageFilter in Spring Boot (tested with 1.3.0.RELEASE), add the following beans to your Spring configuration:
#Bean
public ErrorPageFilter errorPageFilter() {
return new ErrorPageFilter();
}
#Bean
public FilterRegistrationBean disableSpringBootErrorFilter(ErrorPageFilter filter) {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(filter);
filterRegistrationBean.setEnabled(false);
return filterRegistrationBean;
}
The simpliest way to disable ErrorPageFilter is:
#SpringBootApplication
public class App extends SpringBootServletInitializer {
public App() {
super();
setRegisterErrorPageFilter(false); // <- this one
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
#SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//set register error pagefilter false
setRegisterErrorPageFilter(false);
builder.sources(MyApplication.class);
return builder;
}
}
The best way is to tell the WebSphere container to stop ErrorPageFiltering. To achieve this we have to define a property in the server.xml file.
<webContainer throwExceptionWhenUnableToCompleteOrDispatch="false" invokeFlushAfterService="false"></webContainer>
Alternatively, you also can disable it in the spring application.properties file
logging.level.org.springframework.boot.context.web.ErrorPageFilter=off
I prefer the first way.Hope this helps.
I found in the sources that the ErrorPageFilter.java has the following code:
private void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
ErrorWrapperResponse wrapped = new ErrorWrapperResponse(response);
try {
chain.doFilter(request, wrapped);
int status = wrapped.getStatus();
if (status >= 400) {
handleErrorStatus(request, response, status, wrapped.getMessage());
response.flushBuffer();
}
else if (!request.isAsyncStarted() && !response.isCommitted()) {
response.flushBuffer();
}
}
catch (Throwable ex) {
handleException(request, response, wrapped, ex);
response.flushBuffer();
}
}
As you can see when you throw an exception and return a response code >= 400 it will do some code. there should be some additional check if the response was already committed or not.
The way to remove the ErrorPageFilter is like this
protected WebApplicationContext run(SpringApplication application) {
application.getSources().remove(ErrorPageFilter.class);
return super.run(application);
}
Chris
public class Application extends SpringBootServletInitializer
{
private static final Logger logger = LogManager.getLogger(Application.class);
public Application()
{
super();
setRegisterErrorPageFilter(false);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}

Categories

Resources