Unable to get additional tomcat port on https using Spring Boot.

huangapple go评论77阅读模式
英文:

Unable to get additional tomcat port on https using Spring Boot

问题

I have configured additional port to work on https for an REST endpoint. However, while sending request to this endpoint, application does not negotiate over https instead it uses only http. Framework is on Spring Boot 2.7.5.

@Configuration
public class PublicPortConfig {
private static final Logger logger = LogManager.getLogger(PublicPortConfig.class);

@Value("${server.port.public:19280}")
private int port;

@Bean
@ConditionalOnProperty(name = "server.port.public")
public WebServerFactoryCustomizer publicServletContainerCustomizer (
ServerProperties serverProperties) {
logger.info("Configuring public port: {}", port);
return tomcat -> {
Connector connector = new Connector();

    connector.setPort(port);
    connector.setScheme("https");
                
    SSLHostConfig sslHostConfig = new SSLHostConfig();
    
    sslHostConfig.setCertificateKeystoreFile(serverProperties.getSsl().getKeyStore());
    sslHostConfig.setCertificateKeyPassword(serverProperties.getSsl().getKeyStorePassword());
    sslHostConfig.setCertificateKeystoreType(serverProperties.getSsl().getKeyStoreType());

    connector.addSslHostConfig(sslHostConfig);
    
    tomcat.addAdditionalTomcatConnectors(connector);
};

}
}
@RestController
public class ExternalApiController {
@GetMapping("/api/public")
public ResponseEntity hello() {
return ResponseEntity.ok("Hello Customer (public)");
}
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
logger.info("Configuring HttpSecurity via SecurityFilterChain...");
// @formatter:off
http.authorizeRequests()
.antMatchers(AUTH_PATH_WHITELIST).permitAll()
.antMatchers("/api/public/").permitAll()
.antMatchers("/api/admin/
").hasAnyRole("ADMIN")
.antMatchers("/actuator/").hasAnyRole("ADMIN", "ACTUATOR")
.and()
.authorizeRequests().anyRequest().fullyAuthenticated();
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.maximumSessions(MAX_SESSION_ACTIVE);
http.httpBasic()
.realmName("API Auth via DB or LDAP")
.and()
.authenticationProvider(customAuthenticationProvider);
http.csrf().csrfTokenRepository(cookieCsrfTokenRepository());
/

* Force Disable for API
*/
http.csrf().disable();
// http.cors().disable();
// @formatter:on

return http.build();

}

ExternalApiController sends response when request is sent on http and not on https. All fully authenticated endpoints works perfectly well on https.

cURL gives following results

$ curl --insecure -H "Accept: application/json" -H "Content-Type: application/json" -X GET "https://localhost:19280/app/api/public"

Response: curl: (35) LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version
Java Backend Error: java.lang.IllegalArgumentException: Invalid character found in method name
[0x160x030x010x01(0x010x000x01$0x030x030\90xe9}0xef0x980x970x1b+0x820x0f0xc10xbc0xde0x8370xfceI0xdey0x100x1f0x99vJ0xa50x7f_0xd9Y ].
HTTP method names must be tokens

Whereas HTTP request using cURL

$ curl --insecure -H "Accept: application/json" -H "Content-Type: application/json" -X GET "http://localhost:19280/app/api/public"

Response: Hello Customer (public)

Application is started on 2 ports as per below log
INFO 2023-06-06/17:08:18/GMT+05:30 [app-rest-api] (TomcatWebServer.java:220) (start) Tomcat started on port(s): 9280 (https) 19280 (https) with context path 'app'

Port 9280 is ok. However, anything I access on 19280 throws error.

英文:

I have configured additional port to work on https for an REST endpoint. However, while sending request to this endpoint, application does not negotiate over https instead it uses only http. Framework is on Spring Boot 2.7.5.

@Configuration 
public class PublicPortConfig {
private static final Logger logger = LogManager.getLogger(PublicPortConfig.class);

@Value("${server.port.public:19280}")
private int port;

@Bean
@ConditionalOnProperty(name = "server.port.public")
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> publicServletContainerCustomizer (
		ServerProperties serverProperties) {
	logger.info("Configuring public port: {}", port);
	return tomcat -> {			
		Connector connector = new Connector();

		connector.setPort(port);
		connector.setScheme("https");
					
		SSLHostConfig sslHostConfig = new SSLHostConfig();
		
		       sslHostConfig.setCertificateKeystoreFile(serverProperties.getSsl().getKeyStore());
		sslHostConfig.setCertificateKeyPassword(serverProperties.getSsl().getKeyStorePassword());
		sslHostConfig.setCertificateKeystoreType(serverProperties.getSsl().getKeyStoreType());

		connector.addSslHostConfig(sslHostConfig);
        
        tomcat.addAdditionalTomcatConnectors(connector);
	};
}
}
@RestController
public class ExternalApiController {
	@GetMapping("/api/public")
	public ResponseEntity<String> hello() {
		return ResponseEntity.ok("Hello Customer (public)");
	}
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
	logger.info("Configuring HttpSecurity via SecurityFilterChain...");
	// @formatter:off
	http.authorizeRequests()
			.antMatchers(AUTH_PATH_WHITELIST).permitAll()
			.antMatchers("/api/public/**").permitAll()
			.antMatchers("/api/admin/**").hasAnyRole("ADMIN")
			.antMatchers("/actuator/**").hasAnyRole("ADMIN", "ACTUATOR")
			.and()
				.authorizeRequests().anyRequest().fullyAuthenticated();
	http.sessionManagement()
			 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
			 .maximumSessions(MAX_SESSION_ACTIVE);
	http.httpBasic()
		.realmName("API Auth via DB or LDAP")
		.and()
		.authenticationProvider(customAuthenticationProvider);
	http.csrf().csrfTokenRepository(cookieCsrfTokenRepository());
	/**
	 * Force Disable for API
	 */
	http.csrf().disable();
	// http.cors().disable();
	// @formatter:on

	return http.build();
}

ExternalApiController sends response when request is sent on http and not on https. All fully authenticated endpoints works perfectly well on https.

cURL gives following results

$ curl --insecure -H "Accept: application/json" -H "Content-Type: application/json" -X GET "https://localhost:19280/app/api/public"

Response: curl: (35) LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version
Java Backend Error: java.lang.IllegalArgumentException: Invalid character found in method name
[0x160x030x010x01(0x010x000x01$0x030x030\90xe9}0xef0x980x970x1b+0x820x0f0xc10xbc0xde0x8370xfceI0xdey0x100x1f0x99vJ0xa50x7f_0xd9Y ].
HTTP method names must be tokens

Where as http request using cURL

$ curl --insecure -H "Accept: application/json" -H "Content-Type: application/json" -X GET "http://localhost:19280/app/api/public"

Response: Hello Customer (public)

Application is started on 2 ports as per below log
INFO 2023-06-06/17:08:18/GMT+05:30 [app-rest-api] (TomcatWebServer.java:220) (start) Tomcat started on port(s): 9280 (https) 19280 (https) with context path '/app'

Port 9280 is ok. However, anything I access on 19280 throws error.

答案1

得分: 2

几个月前,我在Spring Boot中为我们的REST API启用了https,并在本地测试中使用了自签名证书,该证书是使用Java keytool生成的。

keytool -genkeypair -alias team_api -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore gaskit.p12 -storepass pwd -validity 3650

然后,在application.properties文件中添加以下属性:

server.ssl.key-store-type=${ssl_key_store_type}
# 包含证书的密钥库的路径
server.ssl.key-store=${ssl_key_store}
# 用于生成证书的密码
server.ssl.key-store-password=${ssl_key_store_Password}
# 映射到证书的别名
server.ssl.key-alias=${ssl_key_alias}
server.ssl.enabled=true
英文:

Couple of months back I enabled https for our REST API in Spring boot,used self signed certificate for local testing generated using Java keytool

keytool -genkeypair -alias team_api -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore gaskit.p12 -storepass pwd -validity 3650

And then adding following properties in application.properties

server.ssl.key-store-type=${ssl_key_store_type}
# The path to the keystore containing the certificate
server.ssl.key-store=${ssl_key_store}
# The password used to generate the certificate
server.ssl.key-store-password=${ssl_key_store_Password}
# The alias mapped to the certificate
server.ssl.key-alias=${ssl_key_alias}
server.ssl.enabled=true

答案2

得分: 1

最终通过深入研究Http11NioProtocol我成功地获得了公共/私有Api终端点感谢Spring社区文档[Spring Docs][1]在Tomcat中启用多个连接器部分提供的所有解释

请在下方找到完整的解决方案
1创建用于公共Api的配置文件

@Configuration
@PropertySource("classpath:public-api.properties")
@ConfigurationProperties(prefix = "public.ssl")
@Data
public class PublicApiConfig {
    private int port;
    private String keyStoreType;
    private String keyStore;
    private String keyStorePassword;
    private String keyAlias;
    private List<String> pathsToMatch;
}
2公共Api的配置文件 public-api.properties

public.ssl.port=19280
public.ssl.key-store-type=PKCS12
public.ssl.key-store=ssl/your_certificate.p12
public.ssl.key-store-password=your_password
public.ssl.key-alias=tomcat
public.ssl.paths-to-match=/api/public
3在你的application.properties中定义`server.public.ssl.port.enabled`,其值可以是true公共访问或false

# true表示公共Api访问
server.public.ssl.port.enabled=true
4创建PublicPortCustomizer类

@Component
@ConditionalOnProperty(value = "server.public.ssl.port.enabled", havingValue = "true", matchIfMissing = false)
public class PublicPortCustomizer {

    private static final Logger logger = LogManager.getLogger(PublicPortCustomizer.class);

    @Autowired
    PublicApiConfig publicPortConfig;

    /**
     * 验证KeyStore是否有效
     */
    private boolean isValidKeyStoreFile(String keyStoreFile, String keyStorePassword, String keyStoreType) {
        try {
            File file = new File(keyStoreFile);
            KeyStore keystore = KeyStore.getInstance(keyStoreType);
            FileInputStream fis = new FileInputStream(file);
            keystore.load(fis, keyStorePassword.toCharArray());
            return true;
        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        if (isValidKeyStoreFile(publicPortConfig.getKeyStore(), publicPortConfig.getKeyStorePassword(),
                publicPortConfig.getKeyStoreType())) {
            logger.info("为KeyStore配置公共Ssl: {}", publicPortConfig.getKeyStore());
            /**
             * 创建Connector
             */
            Connector connector = createSslConnector();
            tomcat.addAdditionalTomcatConnectors(connector);
        } else {
            logger.fatal("公共KeyStore: {} 是无效的", publicPortConfig.getKeyStore());
        }
        return tomcat;
    }

    /**
     * 创建Ssl Connector
     * @return
     */
    private Connector createSslConnector() {
        logger.info("配置额外的Ssl Connector...");

        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");

        connector.setScheme("https");
        connector.setSecure(true);
        connector.setPort(publicPortConfig.getPort());

        Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();

        protocol.setSSLEnabled(true);
        protocol.setKeystoreFile(publicPortConfig.getKeyStore());
        protocol.setKeystorePass(publicPortConfig.getKeyStorePassword());
        protocol.setKeyAlias(publicPortConfig.getKeyAlias());

        return connector;
    }
}
5定义SpringSecurity其中公共Api将通过JWT访问该JWT在Controller中进行控制

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SpringSecurityConfig {

    @Autowired
    CustomAuthenticationProvider customAuthenticationProvider;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/api/public/**").permitAll()
                .and()
                .authorizeRequests().anyRequest().fullyAuthenticated();
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.httpBasic()
                .and()
                .authenticationProvider(customAuthenticationProvider);
        http.csrf().disable();
        http.requiresChannel(channel -> channel.anyRequest().requiresSecure());
        return http.build();
    }

    @Bean
    @Lazy
    public FilterRegistrationBean<PublicEndpointsFilter> publicEndpointsFilter() {
        return new FilterRegistrationBean<>(new PublicEndpointsFilter(publicPortConfig.getPort(),
                publicPortConfig.getPathsToMatch()));
    }
}
5a处理公共终端点的过滤器

public class PublicEndpointsFilter implements Filter {

    private static final Logger logger = LogManager.getLogger(PublicEndpointsFilter.class);

    int publicPort;
    List<String> pathsToMatch;

    /**
     * 默认构造函数
     *
     * @param publicPort
     * @param pathsToMatch
     */
    public PublicEndpointsFilter(int publicPort, List<String> pathsToMatch) {
        this.publicPort = publicPort;
        this.pathsToMatch = pathsToMatch;
        logger.info("为publicPort: {} 配置过滤器 pathsToMatch: {}", publicPort, pathsToMatch);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        boolean trustedEndPoint = isRequestForTrustedEndpoint(servletRequest);
        int status = HttpServletResponse.SC_OK;
        ///////////////////////
        if (servletRequest.getLocalPort() == publicPort && !trustedEndPoint) {
            status = HttpServletResponse.SC_FORBIDDEN;
        }
        if (status != HttpServletResponse.SC_OK) {
            logger.warn("在路径上拒绝请求: {} publicPort: {} localPort: {} 状态: {}", request.getRequestURI(),
                    publicPort, servletRequest.getLocalPort(), status);
            response.setStatus(status);
            servletResponse.getOutputStream().close();
            return;
        }
        ///////////////////////
        if (servletRequest.getLocalPort() != publicPort && trustedEndPoint) {
            status = HttpServletResponse.SC_FORBIDDEN;
        }
        if (status != HttpServletResponse.SC_OK) {
            logger.warn("在路径上拒绝请求: {} publicPort: {} localPort: {} 状态: {}", request.getRequestURI(),
                    publicPort, servletRequest.getLocalPort(), status);
            response.setStatus(status);
            servletResponse.getOutputStream().close();
            return;
        }
        logger.debug("在路径上进行过滤委托: {} localPort: {} 状态: {}", request.getRequestURI(),
                request.getLocal

<details>
<summary>英文:</summary>

Finally, I am able to get Public / Private Api EndPoints by deep dive into Http11NioProtocol. Thanks to Spring Community Documents [Spring Docs][1] under Section: Enable Multiple Connectors with Tomcat for all explanations.

Please find complete solution below
1) Create Configuration File for Public Api &lt;pre&gt;&lt;code&gt;
@Configuration
@PropertySource(&quot;classpath:public-api.properties&quot;)
@ConfigurationProperties(prefix = &quot;public.ssl&quot;)
@Data
public class PublicApiConfig {
	private int port;
	private String keyStoreType;
	private String keyStore;
	private String keyStorePassword;
	private String keyAlias;
	private List&lt;String&gt; pathsToMatch;
}
&lt;/code&gt;&lt;/pre&gt;

2) Configuration File public-api.properties &lt;pre&gt;&lt;code&gt;
public.ssl.port=19280
public.ssl.key-store-type=PKCS12
public.ssl.key-store=ssl/your_certificate.p12
public.ssl.key-store-password=your_password
public.ssl.key-alias=tomcat
public.ssl.paths-to-match=/api/public
&lt;/code&gt;&lt;/pre&gt;

3) Define `server.public.ssl.port.enabled` in your application.properties and value could be true (Public Access) or false.
&lt;pre&gt;&lt;code&gt;# true for Public Api Access
server.public.ssl.port.enabled=true&lt;/code&gt;&lt;/pre&gt;
4) Create PublicPortCustomizer class
&lt;pre&gt;&lt;code&gt;@Component
@ConditionalOnProperty(value = &quot;server.public.ssl.port.enabled&quot;, havingValue = &quot;true&quot;, matchIfMissing = false)
public class PublicPortCustomizer {

	private static final Logger logger = LogManager.getLogger(PublicPortCustomizer.class);

	@Autowired
	PublicApiConfig publicPortConfig;

	/**
	 * Verify if KeyStore is Valid
	 */
	private boolean isValidKeyStoreFile(String keyStoreFile, String keyStorePassword, String keyStoreType) {
		try {
			File file = new File(keyStoreFile);
			KeyStore keystore = KeyStore.getInstance(keyStoreType);
			FileInputStream fis = new FileInputStream(file);
			keystore.load(fis, keyStorePassword.toCharArray());
			return true;
		} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	@Bean
	public ServletWebServerFactory servletContainer() {
		TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
		if (isValidKeyStoreFile(publicPortConfig.getKeyStore(), publicPortConfig.getKeyStorePassword(),
				publicPortConfig.getKeyStoreType())) {
			logger.info(&quot;Configuring Ssl Public for KeyStore: {}&quot;, publicPortConfig.getKeyStore());
			/**
			 * Create Connector
			 */
			Connector connector = createSslConnector();
			tomcat.addAdditionalTomcatConnectors(connector);
		} else {
			logger.fatal(&quot;KeyStore for Public: {} is INVALID&quot;, publicPortConfig.getKeyStore());
		}
		return tomcat;
	}

	/**
	 * Create Ssl Connector
	 * @return
	 */
	private Connector createSslConnector() {
		logger.info(&quot;Configuring Additional Ssl Connector...&quot;);

		Connector connector = new Connector(&quot;org.apache.coyote.http11.Http11NioProtocol&quot;);

		connector.setScheme(&quot;https&quot;);
		connector.setSecure(true);
		connector.setPort(publicPortConfig.getPort());

		Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();

		protocol.setSSLEnabled(true);
		protocol.setKeystoreFile(publicPortConfig.getKeyStore());
		protocol.setKeystorePass(publicPortConfig.getKeyStorePassword());
		protocol.setKeyAlias(publicPortConfig.getKeyAlias());

		return connector;
	}
}&lt;/code&gt;&lt;/pre&gt;

  [1]: https://docs.spring.io/spring-boot/docs/2.0.0.M6/reference/html/howto-embedded-web-servers.html

5) Define SpringSecurity where Public Api will be accessed through JWT which is controlled in Controller
&lt;pre&gt;&lt;code&gt;@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SpringSecurityConfig {

	@Autowired
	CustomAuthenticationProvider customAuthenticationProvider;

    @Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.authorizeRequests()
				.antMatchers(&quot;/api/public/**&quot;).permitAll()
				.and()
					.authorizeRequests().anyRequest().fullyAuthenticated();
		http.sessionManagement()
				 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
		http.httpBasic()
			.and()
			.authenticationProvider(customAuthenticationProvider);
		http.csrf().disable();
		http.requiresChannel(channel -&gt; channel.anyRequest().requiresSecure());
		return http.build();
	}
	
	@Bean
	@Lazy
    public FilterRegistrationBean&lt;PublicEndpointsFilter&gt; publicEndpointsFilter() {
        return new FilterRegistrationBean&lt;&gt;(new PublicEndpointsFilter(publicPortConfig.getPort(),
        		publicPortConfig.getPathsToMatch()));
    }
}
 &lt;/code&gt;&lt;/pre&gt;
5a) Filters to handle public endpoints.
&lt;pre&gt;&lt;code&gt;public class PublicEndpointsFilter implements Filter {

	private static final Logger logger = LogManager.getLogger(PublicEndpointsFilter.class);

	int publicPort;
	List&lt;String&gt; pathsToMatch;

	/**
	 * Default Constructor
	 * 
	 * @param publicPort
	 * @param pathsToMatch
	 */
	public PublicEndpointsFilter(int publicPort, List&lt;String&gt; pathsToMatch) {
		this.publicPort = publicPort;
		this.pathsToMatch = pathsToMatch;
		logger.info(&quot;Configuring Filter for publicPort: {} pathsToMatch: {}&quot;, publicPort, pathsToMatch);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		HttpServletResponse response = (HttpServletResponse) servletResponse;

		boolean trustedEndPoint = isRequestForTrustedEndpoint(servletRequest);
		int status = HttpServletResponse.SC_OK;
		///////////////////////
		if (servletRequest.getLocalPort() == publicPort &amp;&amp; !trustedEndPoint) {
			status = HttpServletResponse.SC_FORBIDDEN;
		}
		if (status != HttpServletResponse.SC_OK) {
			logger.warn(&quot;Denying request on path: {} publicPort: {} localPort: {} status: {}&quot;, request.getRequestURI(),
					publicPort, servletRequest.getLocalPort(), status);
			response.setStatus(status);
			servletResponse.getOutputStream().close();
			return;
		}
		///////////////////////
		if (servletRequest.getLocalPort() != publicPort &amp;&amp; trustedEndPoint) {
			status = HttpServletResponse.SC_FORBIDDEN;
		}
		if (status != HttpServletResponse.SC_OK) {
			logger.warn(&quot;Denying request on path: {} publicPort: {} localPort: {} status: {}&quot;, request.getRequestURI(),
					publicPort, servletRequest.getLocalPort(), status);
			response.setStatus(status);
			servletResponse.getOutputStream().close();
			return;
		}
		logger.debug(&quot;Filter Delegate on path: {} localPort: {} status: {}&quot;, request.getRequestURI(),
				request.getLocalPort(), status);
		filterChain.doFilter(servletRequest, response);
	}

	/**
	 * Verify Path as required for Public Access
	 * 
	 * @param servletRequest
	 * @return
	 */
	private boolean isRequestForTrustedEndpoint(ServletRequest servletRequest) {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		boolean ok = false;
		
		for (String pathToMatch : pathsToMatch) {
			String requestPath = request.getContextPath() + pathToMatch;
			ok = request.getRequestURI().startsWith(requestPath);
			logger.debug(&quot;Verified path: {} localPort: {}&quot;, requestPath, servletRequest.getLocalPort());
		}
		return ok;
	}&lt;/code&gt;&lt;/pre&gt;
6) Sample Public / Private Rest Controller
&lt;pre&gt;&lt;code&gt;@RestController
public class PublicApiHelloController {
	@GetMapping(&quot;/api/public&quot;)
	public ResponseEntity&lt;String&gt; hello() {
		return ResponseEntity.ok(&quot;Hello Customer (public)&quot;);
	}
}
@RestController
public class PrivateApiHelloController {
    // Requires Authentication
	@GetMapping(&quot;/api/private&quot;)
	public ResponseEntity&lt;String&gt; hello() {
		return ResponseEntity.ok(&quot;Hello Staff (private)&quot;);
	}
}&lt;/code&gt;&lt;/pre&gt;
7) Start Application and you should see 
&lt;pre&gt;&lt;code&gt;INFO  2023-06-08/08:19:27/GMT+05:30 [app-api] (DirectJDKLog.java:173) (log) Starting ProtocolHandler [&quot;https-jsse-nio-9280&quot;]
INFO  2023-06-08/08:19:27/GMT+05:30 [app-api] (DirectJDKLog.java:173) (log) Starting ProtocolHandler [&quot;https-jsse-nio-19280&quot;]
INFO  2023-06-08/08:19:27/GMT+05:30 [app-api] (TomcatWebServer.java:220) (start) Tomcat started on port(s): 9280 (https) 19280 (https) with context path &#39;/app&#39;
&lt;/code&gt;&lt;/pre&gt;
Make sure ProtocolHandler starts with https-jsse-nio for all https enabled.

8) Public Api Request
&lt;pre&gt;&lt;code&gt;curl --insecure -H &#39;Accept: application/json&#39; -H &#39;Content-Type: application/json&#39; -X GET https://localhost:19280/app/api/public&lt;/code&gt;&lt;/pre&gt;
Response:: Hello Customer (public)

9)Private Api Request
&lt;pre&gt;&lt;code&gt;curl --insecure -H &#39;Accept: application/json&#39; -H &#39;Content-Type: application/json&#39; -X GET https://localhost:9280/app/api/private&lt;/code&gt;&lt;/pre&gt;
Response:: {&quot;timestamp&quot;:1686133851868,&quot;status&quot;:401,&quot;error&quot;:&quot;Unauthorized&quot;,&quot;message&quot;:&quot;Unauthorized&quot;,&quot;path&quot;:&quot;/app/api/private&quot;}

Unauthorized as private expects Authentication

10) Public Ports are configured in firewall to allow traffic

Thanks


</details>



huangapple
  • 本文由 发表于 2023年6月6日 12:08:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76411398.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定