Spring integration (IntegrationFlowContext): Dynamically registering new paths to same websocket server - spring

I was trying to implement spring websocket solution with JavaDsl by following the link i.e https://github.com/joshlong/techtips/tree/master/examples/spring-integration-4.1-websockets-example
And I successfully tested it by subscribing to the path(i.e /messages) with my stomp client.
Next, I tried the same thing by registering the integration flow with IntegrationFlowContext.
It executed successfully on the server-side, but when I tried to make a request by my stomp client I received an exception of 404 not found.
While going through the logs , i found that previously the "AbstractHandlerMapping" was mapping to SockJsHttpRequestHandler and now it is mapping to ResourceHttpRequestHandler
With Spring-managed integration flow (Successful)
DEBUG [http-nio-8081-exec-1] o.s.c.l.LogFormatUtils: GET "/messages/websocket", parameters={}
DEBUG [http-nio-8081-exec-1] o.s.w.s.h.AbstractHandlerMapping: Mapped to org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler#46185a1b
DEBUG [http-nio-8081-exec-1] o.s.w.s.s.s.AbstractSockJsService: Processing transport request: GET http://localhost:8081/messages/websocket
DEBUG [http-nio-8081-exec-1] o.s.w.s.FrameworkServlet: Completed 101 SWITCHING_PROTOCOLS
DEBUG [http-nio-8081-exec-1] o.s.w.s.h.LoggingWebSocketHandlerDecorator: New StandardWebSocketSession[id=e11b5ef5-d2e5-e5c7-819d-493f42f4a7c8, uri=ws://localhost:8081/messages/websocket]
And with IntegrationFlow context managed flow (Failure)
DEBUG [http-nio-8081-exec-1] o.s.c.l.LogFormatUtils: GET "/messages/websocket", parameters={}
DEBUG [http-nio-8081-exec-1] o.s.w.s.h.AbstractHandlerMapping: Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
DEBUG [http-nio-8081-exec-1] o.s.w.s.r.ResourceHttpRequestHandler: Resource not found
DEBUG [http-nio-8081-exec-1] o.s.w.s.FrameworkServlet: Completed 404 NOT_FOUND
DEBUG [http-nio-8081-exec-1] o.s.c.l.LogFormatUtils: "ERROR" dispatch for GET "/error", parameters={}
DEBUG [http-nio-8081-exec-1] o.s.w.s.h.AbstractHandlerMapping: Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
DEBUG [http-nio-8081-exec-1] o.s.w.s.m.m.a.AbstractMessageConverterMethodProcessor: Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
DEBUG [http-nio-8081-exec-1] o.s.c.l.LogFormatUtils: Writing [{timestamp=Tue Feb 25 17:06:58 IST

You have a different Mapped to ... because of getHandler(HttpServletRequest request) logic in the AbstractHandlerMapping:
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
We don't support dynamic WS endpoints because we don't scan them in the internal WebSocketHandlerMappingFactoryBean.
Feel free to raise a GH issue https://github.com/spring-projects/spring-integration/issues and we will take a look what we can do for that.

Related

Why does Post request for an endpoint with same payload returns http 400 for url without trailing slash?

In my controller class , I have an annotated post request method like shown below
#RestController(value="/api")
public class ApiController{
#PostMapping("/post")
#ResponseStatus(HttpStatus.OK)
public ResponseObject postMethod(RequestObject obj){
//service calls
when I call my endpoint with
POST http://localhost:8989/api/post/
with payload my request succesfully hits my controller method.
On the contrary if I only change my request to url with no trailing slash
POST http://localhost:8989/api/post
with exact same payload I get following response from server
{
"timestamp": "2022-11-29T11:23:36.153+03:00",
"status": 400,
"error": "Bad Request",
"message": "",
"path": "/api/post"
}
I enable web logs for spring and below is my trace when I get http 400 from server
[2022-11-29 11:23:36,153] [CID:] [RID:] [http-nio-8989-exec-1] TRACE --- DispatcherServlet : "ERROR" dispatch for POST "/error", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'[2022-11-29 11:23:36,153] [CID:] [RID:] [http-nio-8989-exec-1] TRACE ---
RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
[2022-11-29 11:23:36,153] [CID:] [RID:] [http-nio-8989-exec-1] TRACE --- HandlerMethod : Arguments: [SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.core.ApplicationHttpRequest#3660b306]]]
[2022-11-29 11:23:36,153] [CID:] [RID:] [http-nio-8989-exec-1] DEBUG --- HttpEntityMethodProcessor : Using 'application/json', given [application/json] and supported [application/xml;charset=UTF-8, text/xml;charset=UTF-8, application/+xml;charset=UTF-8, application/json, application/+json, application/x-jackson-smile]
[2022-11-29 11:23:36,154] [CID:] [RID:] [http-nio-8989-exec-1] TRACE --- HttpEntityMethodProcessor : Writing [{timestamp=Tue Nov 29 11:23:36 TRT 2022, status=400, error=Bad Request, message=, path=/api/loanaccount/cancelLimitTransaction}]
[2022-11-29 11:23:36,154] [CID:] [RID:] [http-nio-8989-exec-1] TRACE --- DispatcherServlet : No view rendering, null ModelAndView returned.
I was thinking that if it was a client error , I should have not be able to succesfully call it by just appending trailing slash to url.Because my payload didn't change. How should I troubleshoot this?

CSRF on spring cloud gateway removing formData from POST requests 400 bad request error

I have enabled CSRF on my spring cloud api gateway server.
I have angular as my GUI framework which calls the rest services through the api gateway.
I have used a custom filter to add the CSRF token to the response headers.
When the POST call is made I see that the formData is lost. So I always get 400 Bad request errors.
I disabled CSRF and the request goes through fine without any issues.
Is there something wrong?
Below is my spring cloud gateway configuration. Gateway is used only for routing the requests to other microservices, it does not have any controllers or rest endpoints.
#SpringBootApplication
public class GatewayApplication {
#Autowired
ProfileManager profileManager;
#PostConstruct
public void onInit() {
profileManager.printActiveProfiles();
}
public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); }
#Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http.authorizeExchange().anyExchange().permitAll();
http.csrf().csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse());
return http.build();
}
}
below is the filter code
#Component
public class CsrfHeaderFilter implements WebFilter {
#Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<CsrfToken> token = (Mono<CsrfToken>) exchange.getAttributes().get(CsrfToken.class.getName());
if (token != null) {
return token.flatMap(t -> chain.filter(exchange));
}
return chain.filter(exchange);
}
}
My POST rest endpoints are defined with
#RequestParam
below is the code from one of the rest service endpoints. It is an upstream service implemented using the traditional servlet springboot framework.
#RequestMapping(value = "terminate/{listName}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED)
#CrossOrigin
#Loggable (activityname = ActivityLogConstants.DESCRIPTOR_TERMINATE)
public Response terminate(#Context HttpServletRequest reqContext, #PathVariable String listName, #RequestParam(value = "rowData") String rowData)
throws ServiceException {....}
The formData is lost by the time the request reaches the upstream services.
Looks like the filter in spring cloud gateways is blocking formData
here is my netty configuration:
#Configuration
public class NettyConfiguration implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {
#Value("${server.max-initial-line-length:65536}")
private int maxInitialLingLength;
#Value("${server.max-http-header-size:65536}")
private int maxHttpHeaderSize;
public void customize(NettyReactiveWebServerFactory container) {
container.addServerCustomizers(
httpServer -> httpServer.httpRequestDecoder(
httpRequestDecoderSpec -> {
httpRequestDecoderSpec.maxHeaderSize(maxHttpHeaderSize);
httpRequestDecoderSpec.maxInitialLineLength(maxInitialLingLength);
return httpRequestDecoderSpec;
}
)
);
}
}
below is my application.yml
sample log:
2022-07-28 09:18:20.743 DEBUG 26532 --- [ctor-http-nio-5] r.n.http.client.HttpClientOperations : [id:199cd714-5, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080] Received response (auto-read:false) : [X-Content-Type-Options=nosniff, X-XSS-Protection=1; mode=block, Cache-Control=no-cache, no-store, max-age=0, must-revalidate, Pragma=no-cache, Expires=0, Strict-Transport-Security=max-age=31536000 ; includeSubDomains, X-Frame-Options=DENY, X-Application-Context=application:18080, Date=Thu, 28 Jul 2022 03:48:20 GMT, Connection=close, content-length=0]
2022-07-28 09:18:20.744 DEBUG 26532 --- [ctor-http-nio-5] r.n.r.DefaultPooledConnectionProvider : [id:199cd714-5, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080] onStateChange(POST{uri=/cms-service/webapi/terminate/descriptor, connection=PooledConnection{channel=[id: 0x199cd714, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080]}}, [response_received])
2022-07-28 09:18:20.744 DEBUG 26532 --- [ctor-http-nio-5] reactor.netty.channel.FluxReceive : [id:199cd714-5, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080] FluxReceive{pending=0, cancelled=false, inboundDone=false, inboundError=null}: subscribing inbound receiver
2022-07-28 09:18:20.744 DEBUG 26532 --- [ctor-http-nio-5] r.n.http.client.HttpClientOperations : [id:199cd714-5, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080] Received last HTTP packet
2022-07-28 09:18:20.744 DEBUG 26532 --- [ctor-http-nio-5] r.n.http.server.HttpServerOperations : [id:b0f975eb-11, L:/0:0:0:0:0:0:0:1:10443 - R:/0:0:0:0:0:0:0:1:50337] Decreasing pending responses, now 0
2022-07-28 09:18:20.745 DEBUG 26532 --- [ctor-http-nio-5] r.n.http.server.HttpServerOperations : [id:b0f975eb-11, L:/0:0:0:0:0:0:0:1:10443 - R:/0:0:0:0:0:0:0:1:50337] Last HTTP packet was sent, terminating the channel
2022-07-28 09:18:20.745 DEBUG 26532 --- [ctor-http-nio-5] o.s.w.s.adapter.HttpWebHandlerAdapter : [b0f975eb-11, L:/0:0:0:0:0:0:0:1:10443 - R:/0:0:0:0:0:0:0:1:50337] Completed 400 BAD_REQUEST
2022-07-28 09:18:20.745 DEBUG 26532 --- [ctor-http-nio-5] r.n.http.server.HttpServerOperations : [id:b0f975eb-11, L:/0:0:0:0:0:0:0:1:10443 - R:/0:0:0:0:0:0:0:1:50337] Last HTTP response frame
2022-07-28 09:18:20.745 DEBUG 26532 --- [ctor-http-nio-5] c.m.webgateway.handler.RequestLogger : Total time required to process /cms-service/webapi/terminate/descriptor request 60055
2022-07-28 09:18:20.745 DEBUG 26532 --- [ctor-http-nio-5] r.n.r.DefaultPooledConnectionProvider : [id:199cd714, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080] onStateChange(POST{uri=/cms-service/webapi/terminate/descriptor, connection=PooledConnection{channel=[id: 0x199cd714, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080]}}, [response_completed])
2022-07-28 09:18:20.745 DEBUG 26532 --- [ctor-http-nio-5] r.n.r.DefaultPooledConnectionProvider : [id:199cd714, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080] onStateChange(POST{uri=/cms-service/webapi/terminate/descriptor, connection=PooledConnection{channel=[id: 0x199cd714, L:/127.0.0.1:50342 - R:localhost/127.0.0.1:18080]}}, [disconnecting])
2022-07-28 09:18:20.752 DEBUG 26532 --- [ctor-http-nio-5] r.n.resources.PooledConnectionProvider : [id:199cd714, L:/127.0.0.1:50342 ! R:localhost/127.0.0.1:18080] Channel closed, now: 0 active connections, 4 inactive connections and 0 pending acquire requests.
2022-07-28 09:18:20.752 DEBUG 26532 --- [ctor-http-nio-5] r.n.r.DefaultPooledConnectionProvider : [id:199cd714, L:/127.0.0.1:50342 ! R:localhost/127.0.0.1:18080] onStateChange(PooledConnection{channel=[id: 0x199cd714, L:/127.0.0.1:50342 ! R:localhost/127.0.0.1:18080]}, [disconnecting])
2022-07-28 09:18:23.805 DEBUG 26532 --- [ctor-http-nio-5] r.n.http.server.HttpServerOperations : [id:b0f975eb, L:/0:0:0:0:0:0:0:1:10443 - R:/0:0:0:0:0:0:0:1:50337] Increasing pending responses, now 1
2022-07-28 09:18:23.805 DEBUG 26532 --- [ctor-http-nio-5] reactor.netty.http.server.HttpServer : [id:b0f975eb-12, L:/0:0:0:0:0:0:0:1:10443 - R:/0:0:0:0:0:0:0:1:50337] Handler is being applied: org.springframework.http.server.reactive.ReactorHttpHandlerAdapter#7c82616c
2022-07-28 09:18:23.805 DEBUG 26532 --- [ctor-http-nio-5] o.s.w.s.adapter.HttpWebHandlerAdapter : [b0f975eb-12, L:/0:0:0:0:0:0:0:1:10443 - R:/0:0:0:0:0:0:0:1:50337] HTTP GET "/cms-service/webapi/data/descriptor"
below is the link to the sample project.
https://github.com/manjosh1990/webgateway-issues
I tried to ignore FORM URL ENCODED requests and GET request, but it still does not work
private static final Set<HttpMethod> ALLOWED_METHODS = new HashSet<>(
Arrays.asList(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.TRACE, HttpMethod.OPTIONS));
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.authorizeExchange().anyExchange().permitAll().and()
.csrf(csrf -> csrf
.requireCsrfProtectionMatcher(ignoringFormUrlEncodedContentType())
.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse()));
return http.build();
}
private ServerWebExchangeMatcher ignoringFormUrlEncodedContentType() {
return (exchange) -> !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(
exchange.getRequest().getHeaders().getContentType()) || !ALLOWED_METHODS.contains(exchange.getRequest().getMethod())
? ServerWebExchangeMatcher.MatchResult.match()
: ServerWebExchangeMatcher.MatchResult.notMatch();
}
Thanks for the minimal sample to reproduce the issue!
After some testing, I'm unable to come up with a workaround or fix for your configuration that allows a form post (URL-encoded) to pass through the gateway with CSRF protection enabled. My best guess is it has to do with how Spring Security is consuming the request body (which should be cached for subsequent filters to consume) vs how Spring Cloud Gateway is consuming the request body in order to proxy to the downstream service.
I tested this by disabling CSRF protection and adding the following filter:
#Component
public class TestWebFilter implements WebFilter {
#Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return Mono.defer(() -> exchange.getFormData()
.doOnSuccess(System.out::println))
.then(chain.filter(exchange));
}
}
In my testing, this causes the request through the gateway to block for a long time before receiving:
{
"timestamp": "2022-08-10T19:13:54.265+00:00",
"status": 400,
"error": "Bad Request",
"path": "/cms-service/webapi/service/post/test"
}
Since this appears to be a bug in Spring Security, I'd recommend submitting a bug in Spring Security and we can work through it from there.
If you would like to work around the issue in the meantime, you can disable CSRF protection for these types of requests, as follows:
#Configuration
#EnableWebFluxSecurity
public class SecurityConfig {
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange((authorize) -> authorize
.anyExchange().authenticated()
)
.csrf((csrf) -> csrf
.requireCsrfProtectionMatcher(ignoringFormUrlEncodedContentType())
.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
)
.oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt);
return http.build();
}
private ServerWebExchangeMatcher ignoringFormUrlEncodedContentType() {
return (exchange) -> !MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(
exchange.getRequest().getHeaders().getContentType())
? ServerWebExchangeMatcher.MatchResult.match()
: ServerWebExchangeMatcher.MatchResult.notMatch();
}
}
Important: This is not ideal, because these requests won't be protected. However, this might make sense if these requests were never performed in a browser. In that case, it would make sense to have a separate authentication mechanism, such as requiring a bearer token instead of form login, etc. (as in the example above).

SpringBoot RestApi call 404 Not Found error

I have a SpringBoot application that I am able to start ( http://localhost:80 ).
In my application.yml :
application:
baseurl: /respViewer/api
In my application I defined a #RestController and an endpoint :
#RestController
#RequestMapping("${application.baseurl}/viewer")
....
#PostMapping(value = "/getRespList", consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> getResponsibilities(#RequestBody RequestDetail requestDetail)
When I try to access my application using Insomnia or through the Browser I am getting 404 Error.
http://localhost:8080/respViewer/api/viewer/getRespList
{
"timestamp": "2022-04-25T19:52:32.426+00:00",
"status": 404,
"error": "Not Found",
"message": "",
"path": "/respViewer/api/viewer/getRespList"
}
I also checked console output and found these messages :
POST "/respViewer/api/viewer/getRespList", parameters={}
2022-04-25 15:52:32.253 DEBUG 3744 --- [nio-8080-exec-1] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2022-04-25 15:52:32.382 DEBUG 3744 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2022-04-25 15:52:32.387 DEBUG 3744 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : Completed 404 NOT_FOUND
What am I doing wrong?
Update 1 :
I added packages location where I have a REST Controller to application.yml :
spring:
component:
scan:
packages: com.example.demoRespManager
and now I am not getting 404 Error, however it doesn't look like I am getting into the body of implementation method. I setup a break-point in the first line of the method but never stop there. An output in the Console is :
2022-04-25 21:25:43.749 INFO 27996 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-04-25 21:25:43.750 DEBUG 27996 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : Detected StandardServletMultipartResolver
2022-04-25 21:25:43.915 DEBUG 27996 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2022-04-25 21:25:43.915 INFO 27996 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : Completed initialization in 166 ms
2022-04-25 21:25:44.134 DEBUG 27996 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : POST "/respViewer/api/viewer/getRespList", parameters={}
2022-04-25 21:25:44.180 DEBUG 27996 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Using #ExceptionHandler com.<my_package_path>.exception.ApplicationExceptionHandler#handleException(Exception, WebRequest)
2022-04-25 21:25:44.254 DEBUG 27996 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : No match for [application/json], supported: []
2022-04-25 21:25:44.261 DEBUG 27996 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supported]
2022-04-25 21:25:44.262 DEBUG 27996 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : Completed 415 UNSUPPORTED_MEDIA_TYPE
UPDATE 2 :
In the Header section of the INSOMNIA application I added Content-type = application/json, since I defined it in my endpoint, and after that it started to work. I was able to start an application in the DEBUG mode and when I made a POST request in INSOMNIA I stopped at the first line of my method implementation.
I solved this issue :
updated my properties file with the list of the packages that contain the beans, it's an equivalent of #ComponentScan in Application ( spring.component.scan.packages )
Added Content-type = application/json to the Header in the Insomnia.

Trace Id not getting sent correctly between spring boot apps

I have a spring boot console app that sends a http request to a spring boot api, the trace id looks correct in the console app, but is a completely different trace id in the api side. Why would this happen? Do I need to inject something into the trace context in the console app? Thanks for any help!
Console app:
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
logger.info("right before setting header");
MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
header.add("X-B3-TraceId", "b3c10720b744fa9d");
header.add("X-B3-SpanId", "b3c10720b744fa9d");
logger.info("right before rest template");
restTemplate
.exchange(builder.build(false).toUriString(), HttpMethod.POST,
new HttpEntity<>("some request body", header), String.class);
logger.info("after rest template");
console app log(b3c10720b744fa9d is expected trace id):
2020-11-13T18:49:41.686 INFO [-,b3c10720b744fa9d,,] 16268 --- [ main] c.m.f.s.common.impl.TrackingServiceImpl : right before setting header
2020-11-13T18:49:41.687 INFO [-,b3c10720b744fa9d,,] 16268 --- [ main] c.m.f.s.common.impl.TrackingServiceImpl : right before rest template
api:
#PostMapping("/trace")
public #ResponseBody ResponseEntity postTracking(
#RequestBody String jsonRequest, HttpServletRequest httpRequest) {
List<String> headers = Collections.list(httpRequest.getHeaderNames());
headers.forEach(header -> logger.info("Header {} Value {}", header, httpRequest.getHeader(header)));
api logs (now showing 221cd9ce3908aa1a as trace id):
2020-11-15 17:19:12.814 INFO [-,221cd9ce3908aa1a,221cd9ce3908aa1a,false] 22372 --- [nio-8081-exec-1] c.m.f.t.controller.TrackingController : Header accept Value text/plain, application/json, application/cbor, application/*+json,
2020-11-15 17:19:12.815 INFO [-,221cd9ce3908aa1a,221cd9ce3908aa1a,false] 22372 --- [nio-8081-exec-1] c.m.f.t.controller.TrackingController : Header content-type Value text/plain;charset=UTF-8
2020-11-15 17:19:12.815 INFO [-,221cd9ce3908aa1a,221cd9ce3908aa1a,false] 22372 --- [nio-8081-exec-1] c.m.f.t.controller.TrackingController : Header x-b3-traceid Value 221cd9ce3908aa1a
2020-11-15 17:19:12.815 INFO [-,221cd9ce3908aa1a,221cd9ce3908aa1a,false] 22372 --- [nio-8081-exec-1] c.m.f.t.controller.TrackingController : Header x-b3-spanid Value 221cd9ce3908aa1a
2020-11-15 17:19:12.815 INFO [-,221cd9ce3908aa1a,221cd9ce3908aa1a,false] 22372 --- [nio-8081-exec-1] c.m.f.t.controller.TrackingController : Header x-b3-sampled Value 0

How to disable hawt.io authentication?

I used spring boot, hawt.io, camel to test hawt.io dashboard
plugins {
id 'org.springframework.boot' version '1.5.10.RELEASE'
}
repositories {
mavenCentral()
flatDir {
dirs 'lib'
}
}
dependencies {
// Spring actuator, log4j2
compile("org.springframework.boot:spring-boot-starter-log4j2")
//Spring web
compile("org.springframework.boot:spring-boot-starter-web"){
exclude module: "spring-boot-starter-tomcat"
}
compile("org.springframework.boot:spring-boot-starter-jetty")
compile("org.eclipse.jetty:jetty-jaas")
compile("org.eclipse.jetty:jetty-http")
compile("org.springframework.boot:spring-boot-actuator")
//hawtio
compile("io.hawt:hawtio-springboot:1.5.10")
compile("io.hawt:hawtio-core:1.5.10")
and i had disabled authentication via
hawtio.authenticationEnabled=false
Here is the log:
18:00:13.489 [main] DEBUG ConfigManager - Property noCredentials401 is set to value false
18:00:13.490 [main] DEBUG ConfigManager - Property realm is set to value karaf
18:00:13.490 [main] DEBUG ConfigManager - Property role is set to value null
18:00:13.490 [main] DEBUG ConfigManager - Property roles is set to value null
18:00:13.490 [main] DEBUG ConfigManager - Property rolePrincipalClasses is set to value
18:00:13.490 [main] DEBUG ConfigManager - Property authenticationEnabled is set to value false
18:00:13.490 [main] DEBUG ConfigManager - Property noCredentials401 is set to value false
18:00:13.490 [main] DEBUG ConfigManager - Property authenticationContainerDiscoveryClasses is set to value io.hawt.web.tomcat.TomcatAuthenticationContainerDiscovery
18:00:13.490 [main] INFO AuthenticationFilter - Starting hawtio authentication filter, JAAS authentication disabled
18:00:13.500 [main] DEBUG ConfigManager - Property sessionTimeout is set to value 1800
18:00:13.500 [main] INFO LoginServlet - hawtio login is using 1800 sec. HttpSession timeout
When i open url http://localhost:8091/hawtio/index.html, it always be redirected to http://localhost:8091/hawtio/index.html#/login
How can i disable authentication?
According https://github.com/hawtio/hawtio/issues/1963, the issue should be fixed on 6 Dec 2015, but it's still there.
And according those 404 errors, it seems all requests are handled by spring mvc DispatcherServlet, and those servlets registered in HawtioManagementContextConfiguration are not worked as expected.
18:07:52.821 [qtp1016881733-22] DEBUG DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/hawtio/keycloak/enabled]
18:07:52.821 [qtp1016881733-22] DEBUG RequestMappingHandlerMapping - Looking up handler method for path /hawtio/keycloak/enabled
18:07:52.821 [qtp1016881733-22] DEBUG RequestMappingHandlerMapping - Did not find handler method for [/hawtio/keycloak/enabled]
18:07:52.821 [qtp1016881733-22] DEBUG SimpleUrlHandlerMapping - Matching patterns for request [/hawtio/keycloak/enabled] are [/hawtio/**, /**]
18:07:52.821 [qtp1016881733-22] DEBUG SimpleUrlHandlerMapping - URI Template variables for request [/hawtio/keycloak/enabled] are {}
18:07:52.822 [qtp1016881733-22] DEBUG SimpleUrlHandlerMapping - Mapping [/hawtio/keycloak/enabled] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], ServletContext resource [/app/], class path resource [hawtio-static/], class path resource [hawtio-static/app/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#244d7ca5]]] and 1 interceptor
18:07:52.822 [qtp1016881733-22] DEBUG DispatcherServlet - Last-Modified value for [/hawtio/keycloak/enabled] is: -1
18:07:52.824 [qtp1016881733-22] DEBUG DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
18:07:52.824 [qtp1016881733-22] DEBUG RequestMappingHandlerMapping - Looking up handler method for path /error
18:07:52.825 [qtp1016881733-22] DEBUG RequestMappingHandlerMapping - Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
18:07:52.825 [qtp1016881733-22] DEBUG DispatcherServlet - Last-Modified value for [/error] is: -1
18:07:52.833 [qtp1016881733-22] DEBUG ContentNegotiatingViewResolver - Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html])
18:07:52.833 [qtp1016881733-22] DEBUG BeanNameViewResolver - No matching bean found for view name 'error.html'
18:07:52.838 [qtp1016881733-22] DEBUG ContentNegotiatingViewResolver - Returning [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#150fc7a7] based on requested media type 'text/html'
18:07:52.838 [qtp1016881733-22] DEBUG DispatcherServlet - Rendering view [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#150fc7a7] in DispatcherServlet with name 'dispatcherServlet'
18:07:52.886 [qtp1016881733-22] DEBUG DispatcherServlet - Successfully completed request
18:07:52.887 [qtp1016881733-22] DEBUG DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
18:07:52.887 [qtp1016881733-22] DEBUG DispatcherServlet - Successfully completed request
18:07:52.965 [qtp1016881733-47] DEBUG DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/favicon.ico]
18:07:52.965 [qtp1016881733-47] DEBUG SimpleUrlHandlerMapping - Matching patterns for request [/favicon.ico] are [/**/favicon.ico]
18:07:52.965 [qtp1016881733-47] DEBUG SimpleUrlHandlerMapping - URI Template variables for request [/favicon.ico] are {}
18:07:52.965 [qtp1016881733-47] DEBUG SimpleUrlHandlerMapping - Mapping [/favicon.ico] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#ec04917]]] and 1 interceptor
18:07:52.965 [qtp1016881733-47] DEBUG DispatcherServlet - Last-Modified value for [/favicon.ico] is: -1
18:07:52.969 [qtp1016881733-47] DEBUG DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
18:07:52.969 [qtp1016881733-47] DEBUG DispatcherServlet - Successfully completed request
Mostly the reason is that you just forget the final required step to use Hawtio with Spring Boot. You need this line in your application.properties:
endpoints.jolokia.sensitive = false
Without this setting Jolokia endpoint always returns 401 for unauthenticated requests, thus causing redirects to the login page.
You can also refer to a working example of unauthenticated Hawtio with Spring Boot here:
https://github.com/hawtio/hawtio/tree/master/hawtio-sample-springboot
By the way, Hawtio 2.0 will be released very soon.
Finally, i found the root cause is that
management.port != server.port
I referenced this one SpringBootCamelStarter, i also used 8095 for management port and 8091 for server port, and i used the normal server port 8091 to access it, that's the issue, i should use management port 8095 to access hawtio dashboard. here is the clear description:https://github.com/hawtio/hawtio/tree/2.x/examples/springboot

Resources