java - springboot 战争适用于嵌入式 tomcat,但不适用于外部 tomcat
问题描述
我一直在开发一个带有 spring security 的 springboot 2.3.4 应用程序。它适用于嵌入式 tomcat。我们想让它与外部应用程序服务器(如 tomcat 和 jboss)一起工作。我试图将war文件部署在外部tomcat服务器中。到达端点时,我收到 404 错误代码。这是我的pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.teradata</groupId>
<artifactId>modelstudio</artifactId>
<version>1</version>
<name>modelstudio</name>
<packaging>war</packaging>
<description>ModelStudio Application</description>
<properties>
<java.version>13</java.version>
<start-class>
com.teradata.modelstudio.ModelStudioApplication
</start-class>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.teradata.jdbc</groupId>
<artifactId>terajdbc4</artifactId>
<version>17</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>modelstudio</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>static/**</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>ModelStudioUI/**</exclude>
<exclude>static/**</exclude>
</excludes>
</resource>
</resources>
</build>
</project>
我的 JWT 入口点是:
package com.teradata.modelstudio.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.teradata.modelstudio.service.CustomAuthenticationProviderService;
import com.teradata.modelstudio.utils.JwtUtil;
import com.teradata.modelstudio.utils.Logger;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Pattern;
@Component
public class JwtFilter extends OncePerRequestFilter {
@Autowired
private JwtUtil jwtUtil;
@Autowired
private CustomAuthenticationProviderService service;
@Autowired JwtUserDetailsService jwtUserDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
String requestURI = httpServletRequest.getRequestURI();
Logger.info("==================="+requestURI);
Pattern mega = Pattern.compile(
"\\/*.css|\\/*.js|\\/*.png|\\/*.jpg|\\/assets\\/*.*|\\/*.woff2|\\/*.woff|\\/*.ttf|\\/swagger-resources\\/*|/servicemanagement/configuration/*|/servicemanagement/etlframework/*|/servicemanagement/refreshCache/*");
// System.out.println(requestURI);
if (httpServletRequest.getMethod().equals("OPTIONS")// || requestURI.equalsIgnoreCase("/index.html")
|| requestURI.equalsIgnoreCase("/favicon.ico") || mega.matcher(requestURI).find() || requestURI.equalsIgnoreCase("/")) {
filterChain.doFilter(httpServletRequest, httpServletResponse);
return;
}
// TODO Auto-generated method stub
String url = httpServletRequest.getRequestURL().toString();
// System.out.println("+++URL in jwt request filter:"+url);
if (url.contains("auth") || url.contains("dbcontent") || url.contains("favico")) {
filterChain.doFilter(httpServletRequest, httpServletResponse);
return;
}
String requestTokenHeader = httpServletRequest.getHeader("Authorization");
String username = null;
String password = null;
String serverUrl = null;
String dbName = null;
String authType = null;
String jwtToken = null;
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtUtil.getUsernameFromJWT(jwtToken);
password = jwtUtil.getPasswordFromJWT(jwtToken);
serverUrl = jwtUtil.getServerUrlFromJWT(jwtToken);
dbName = jwtUtil.getDbNameFromJWT(jwtToken);
authType = jwtUtil.getAuthTypeFromJWT(jwtToken);
jwtUtil.validateToken(jwtToken, username);
} catch (Exception e) {
throw e;
}
} else {
throw new IOException("Invalid Authorization");
}
SecurityContextHolder.getContext().setAuthentication(null);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwtToken, username)) {
CustomUserPrincipal customUserPrincipal = new CustomUserPrincipal(username, password, serverUrl, dbName, authType);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(customUserPrincipal, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
我的安全配置文件:
package com.teradata.modelstudio.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.teradata.modelstudio.filter.JwtFilter;
import com.teradata.modelstudio.payload.JwtAuthenticationResponse;
import com.teradata.modelstudio.security.JwtAuthenticationEntryPoint;
import com.teradata.modelstudio.service.CustomAuthenticationProviderService;
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProviderService authenticationProviderService;
@Autowired
private JwtFilter jwtFilter;
@Autowired
JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private com.teradata.modelstudio.filter.SimpleCORSFilter simpleCORSFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/*.svg",
"/*.png",
"/*.woff",
"/*.woff2",
"/*.svg",
"/*.jpg",
"/*.json",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**/*.svg",
"/**/*.png",
"/**/*.jpg",
"/**/*.ico",
"/**/*.icons",
"/resources/**",
"/assets/",
"/static/**",
"/h2-console/**"
).permitAll()
.antMatchers("/auth/**", "/dbcontent/**")
.permitAll()
.anyRequest().authenticated()
.and().exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(simpleCORSFilter, UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderService);
}
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
我的控制器类之一是:
package com.teradata.modelstudio.controllers;
import java.io.File;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.teradata.modelstudio.exception.ModelStudioException;
import com.teradata.modelstudio.utils.Logger;
import org.apache.commons.io.FileUtils;
import org.json.JSONObject;
@RestController
@RequestMapping("dbcontent")
public class DBContentController {
@GetMapping(path="servers", produces = "application/json")
public ResponseEntity<?> getServers() {
try {
String dbConFilePath = System.getProperty("user.dir")+File.separator+"db-con";
File file = new File(dbConFilePath);
String content = FileUtils.readFileToString(file, "utf-8");
// Convert JSON string to JSONObject
JSONObject fileContents = new JSONObject(content);
return ResponseEntity.ok(fileContents.toString());
} catch(Exception e) {
Logger.error("Unable to get servers: "+e.getMessage());
throw new ModelStudioException(e.getMessage());
}
}
}
这是我的主要课程
package com.teradata.modelstudio;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication(
exclude = { DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
})
public class ModelstudioApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(ModelstudioApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(ModelstudioApplication.class);
}
}
使用嵌入式 tomcat 服务器,我点击:
本地主机:8080/dbcontent/servers
我在外部得到结果,我执行以下操作:
本地主机:8080/modelstudio/dbcontent/servers
我得到404。
谁能帮助并建议我如何使用外部服务器(如tomcat)解决此问题。
解决方案
推荐阅读
- reactjs - 使用 react-apollo useMutation hook 处理错误
- android - 如何在 Android 10、Target API 29 中从设备的共享存储(根目录)读取现有文件?
- python - 我收到登录路由 TypeError 的错误:'int' object is not subscriptable
- azure - 无法使用 ansible 从捕获的 azure 映像创建 VM
- java - 持有人cardview更改textview颜色错误
- bash - shell script to Start/Stop tomcat server
- android - 保护应用免于绕过根检测(Frida Server)
- java - 如何在火花中处理这种情况?
- maven - Maven跳过测试资源的副本
- transformer - Huggingface 变形金刚 - AttributeError:“MrpcProcessor”对象没有属性“tfds_map”