updated transport http limits, added logging for initialized filters
This commit is contained in:
		
							parent
							
								
									4169da4c08
								
							
						
					
					
						commit
						936bb82334
					
				@ -57,7 +57,7 @@ import org.thingsboard.server.service.security.auth.oauth2.HttpCookieOAuth2Autho
 | 
			
		||||
import org.thingsboard.server.service.security.auth.rest.RestAuthenticationProvider;
 | 
			
		||||
import org.thingsboard.server.service.security.auth.rest.RestLoginProcessingFilter;
 | 
			
		||||
import org.thingsboard.server.service.security.auth.rest.RestPublicLoginProcessingFilter;
 | 
			
		||||
import org.thingsboard.server.transport.http.config.RequestSizeFilter;
 | 
			
		||||
import org.thingsboard.server.transport.http.config.PayloadSizeFilter;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
@ -84,7 +84,7 @@ public class ThingsboardSecurityConfiguration {
 | 
			
		||||
    public static final String MAIL_OAUTH2_PROCESSING_ENTRY_POINT = "/api/admin/mail/oauth2/code";
 | 
			
		||||
    public static final String DEVICE_CONNECTIVITY_CERTIFICATE_DOWNLOAD_ENTRY_POINT = "/api/device-connectivity/mqtts/certificate/download";
 | 
			
		||||
 | 
			
		||||
    @Value("${server.http.max_payload_size:/api/image*/**=52428800;/api/**=16777216}")
 | 
			
		||||
    @Value("${server.http.max_payload_size:/api/image*/**=52428800;/api/resource/**=52428800;/api/**=16777216}")
 | 
			
		||||
    private String maxPayloadSizeConfig;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
@ -130,8 +130,8 @@ public class ThingsboardSecurityConfiguration {
 | 
			
		||||
    private RateLimitProcessingFilter rateLimitProcessingFilter;
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    protected RequestSizeFilter requestSizeFilter() {
 | 
			
		||||
        return new RequestSizeFilter(maxPayloadSizeConfig);
 | 
			
		||||
    protected PayloadSizeFilter payloadSizeFilter() {
 | 
			
		||||
        return new PayloadSizeFilter(maxPayloadSizeConfig);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
@ -234,7 +234,7 @@ public class ThingsboardSecurityConfiguration {
 | 
			
		||||
                .addFilterBefore(buildRestPublicLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
 | 
			
		||||
                .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
 | 
			
		||||
                .addFilterBefore(buildRefreshTokenProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
 | 
			
		||||
                .addFilterBefore(requestSizeFilter(), UsernamePasswordAuthenticationFilter.class)
 | 
			
		||||
                .addFilterBefore(payloadSizeFilter(), UsernamePasswordAuthenticationFilter.class)
 | 
			
		||||
                .addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class);
 | 
			
		||||
        if (oauth2Configuration != null) {
 | 
			
		||||
            http.oauth2Login(login -> login
 | 
			
		||||
 | 
			
		||||
@ -52,8 +52,8 @@ server:
 | 
			
		||||
        key_password: "${SSL_KEY_PASSWORD:thingsboard}"
 | 
			
		||||
  # HTTP settings
 | 
			
		||||
  http:
 | 
			
		||||
    # Semi-colon-separated list of urlPattern=maxPayloadSize pairs that define max http request size for specified url pattern.
 | 
			
		||||
    max_payload_size: "${HTTP_MAX_PAYLOAD_SIZE_LIMIT_CONFIGURATION:/api/image*/**=52428800;/api/**=16777216}"
 | 
			
		||||
    # Semi-colon-separated list of urlPattern=maxPayloadSize pairs that define max http request size for specified url pattern. After first match all other will be skipped
 | 
			
		||||
    max_payload_size: "${HTTP_MAX_PAYLOAD_SIZE_LIMIT_CONFIGURATION:/api/image*/**=52428800;/api/resource/**=52428800;/api/**=16777216}"
 | 
			
		||||
  # HTTP/2 support (takes effect only if server SSL is enabled)
 | 
			
		||||
  http2:
 | 
			
		||||
    # Enable/disable HTTP/2 support
 | 
			
		||||
@ -963,8 +963,8 @@ transport:
 | 
			
		||||
    request_timeout: "${HTTP_REQUEST_TIMEOUT:60000}"
 | 
			
		||||
    # HTTP maximum request processing timeout in milliseconds
 | 
			
		||||
    max_request_timeout: "${HTTP_MAX_REQUEST_TIMEOUT:300000}"
 | 
			
		||||
    # Semi-colon-separated list of urlPattern=maxPayloadSize pairs that define max http request size for specified url pattern.
 | 
			
		||||
    max_payload_size: "${HTTP_MAX_PAYLOAD_SIZE_LIMIT_CONFIGURATION:/api/v1/*/attributes=52428800;/api/v1/**=65536}"
 | 
			
		||||
    # Semi-colon-separated list of urlPattern=maxPayloadSize pairs that define max http request size for specified url pattern. After first match all other will be skipped
 | 
			
		||||
    max_payload_size: "${HTTP_TRANSPORT_MAX_PAYLOAD_SIZE_LIMIT_CONFIGURATION:/api/v1/*/rpc/**=65536;/api/v1/**=52428800}"
 | 
			
		||||
  # Local MQTT transport parameters
 | 
			
		||||
  mqtt:
 | 
			
		||||
    # Enable/disable mqtt transport protocol.
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -42,7 +42,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 | 
			
		||||
 */
 | 
			
		||||
@TestPropertySource(properties = {
 | 
			
		||||
        "transport.http.enabled=true",
 | 
			
		||||
        "transport.http.max_payload_size=/api/v1/*/attributes=20000;/api/v1/**=10000"
 | 
			
		||||
        "transport.http.max_payload_size=/api/v1/*/rpc/**=10000;/api/v1/**=20000"
 | 
			
		||||
})
 | 
			
		||||
public abstract class BaseHttpDeviceApiTest extends AbstractControllerTest {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@ public class MaxPayloadSizeExceededException extends RuntimeException {
 | 
			
		||||
    private final long limit;
 | 
			
		||||
 | 
			
		||||
    public MaxPayloadSizeExceededException(long limit) {
 | 
			
		||||
        super("Payload size exceeds the limit " + limit);
 | 
			
		||||
        super("Payload size exceeds the limit of " + limit + " bytes");
 | 
			
		||||
        this.limit = limit;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -33,12 +33,12 @@ import java.util.Map;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class RequestSizeFilter extends OncePerRequestFilter {
 | 
			
		||||
public class PayloadSizeFilter extends OncePerRequestFilter {
 | 
			
		||||
 | 
			
		||||
    private final Map<String, Long> limits = new LinkedHashMap<>();
 | 
			
		||||
    private final AntPathMatcher pathMatcher = new AntPathMatcher();
 | 
			
		||||
 | 
			
		||||
    public RequestSizeFilter(String limitsConfiguration) {
 | 
			
		||||
    public PayloadSizeFilter(String limitsConfiguration) {
 | 
			
		||||
        for (String limit : limitsConfiguration.split(";")) {
 | 
			
		||||
            try {
 | 
			
		||||
                String urlPathPattern = limit.split("=")[0];
 | 
			
		||||
@ -48,6 +48,7 @@ public class RequestSizeFilter extends OncePerRequestFilter {
 | 
			
		||||
                throw new IllegalArgumentException("Failed to parse size limits configuration: " + limitsConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        log.info("Initialized payload size filter with configuration: {}" , limitsConfiguration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -65,9 +66,7 @@ public class RequestSizeFilter extends OncePerRequestFilter {
 | 
			
		||||
 | 
			
		||||
    private boolean checkMaxPayloadSizeExceeded(HttpServletRequest request, HttpServletResponse response, long maxPayloadSize) throws IOException {
 | 
			
		||||
        if (request.getContentLength() > maxPayloadSize) {
 | 
			
		||||
            if (log.isDebugEnabled()) {
 | 
			
		||||
                log.debug("Too large payload size. Url: {}, client ip: {}, content length: {}", request.getRequestURL(), request.getRemoteAddr(), request.getContentLength());
 | 
			
		||||
            }
 | 
			
		||||
            log.info("[{}] [{}] Payload size {} exceeds the limit of {} bytes", request.getRemoteAddr(), request.getRequestURL(), request.getContentLength(), maxPayloadSize);
 | 
			
		||||
            handleMaxPayloadSizeExceededException(response, new MaxPayloadSizeExceededException(maxPayloadSize));
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@ -16,8 +16,6 @@
 | 
			
		||||
package org.thingsboard.server.transport.http.config;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 | 
			
		||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.core.annotation.Order;
 | 
			
		||||
@ -32,17 +30,15 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 | 
			
		||||
@Configuration
 | 
			
		||||
@EnableWebSecurity
 | 
			
		||||
@EnableMethodSecurity
 | 
			
		||||
@Order(SecurityProperties.BASIC_AUTH_ORDER)
 | 
			
		||||
@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.http.enabled}'=='true')")
 | 
			
		||||
public class TransportSecurityConfiguration {
 | 
			
		||||
    public static final String DEVICE_API_ENTRY_POINT = "/api/v1/**";
 | 
			
		||||
 | 
			
		||||
    @Value("${transport.http.max_payload_size:/api/v1/*/attributes=52428800;/api/v1/**=65536}")
 | 
			
		||||
    @Value("${transport.http.max_payload_size:/api/v1/*/rpc/**=65536;/api/v1/**=52428800}")
 | 
			
		||||
    private String maxPayloadSizeConfig;
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    protected RequestSizeFilter httpTransportRequestSizeFilter() {
 | 
			
		||||
        return new RequestSizeFilter(maxPayloadSizeConfig);
 | 
			
		||||
    protected PayloadSizeFilter transportPayloadSizeFilter() {
 | 
			
		||||
        return new PayloadSizeFilter(maxPayloadSizeConfig);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
@ -55,7 +51,7 @@ public class TransportSecurityConfiguration {
 | 
			
		||||
                .csrf(AbstractHttpConfigurer::disable)
 | 
			
		||||
                .authorizeHttpRequests(config -> config
 | 
			
		||||
                        .requestMatchers(DEVICE_API_ENTRY_POINT).permitAll())
 | 
			
		||||
                .addFilterBefore(httpTransportRequestSizeFilter(), UsernamePasswordAuthenticationFilter.class);
 | 
			
		||||
                .addFilterBefore(transportPayloadSizeFilter(), UsernamePasswordAuthenticationFilter.class);
 | 
			
		||||
        return http.build();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -170,8 +170,8 @@ transport:
 | 
			
		||||
    request_timeout: "${HTTP_REQUEST_TIMEOUT:60000}"
 | 
			
		||||
    # HTTP maximum request processing timeout in milliseconds
 | 
			
		||||
    max_request_timeout: "${HTTP_MAX_REQUEST_TIMEOUT:300000}"
 | 
			
		||||
    # Semi-colon-separated list of urlPattern=maxPayloadSize pairs that define max http request size for specified url pattern.
 | 
			
		||||
    max_payload_size: "${HTTP_MAX_PAYLOAD_SIZE_LIMIT_CONFIGURATION:/api/v1/*/attributes=52428800;/api/v1/**=65536}"
 | 
			
		||||
    # Semi-colon-separated list of urlPattern=maxPayloadSize pairs that define max http request size for specified url pattern. After first match all other will be skipped
 | 
			
		||||
    max_payload_size: "${HTTP_TRANSPORT_MAX_PAYLOAD_SIZE_LIMIT_CONFIGURATION:/api/v1/*/rpc/**=65536;/api/v1/**=52428800}"
 | 
			
		||||
  sessions:
 | 
			
		||||
    # Session inactivity timeout is a global configuration parameter that defines how long the device transport session will be opened after the last message arrives from the device.
 | 
			
		||||
    # The parameter value is in milliseconds.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user