提交 ce06929c authored 作者: Matrix's avatar Matrix

增加了JWT模块,暂停了所有模块的定时任务(原因是要暂时上一版只提供API的版本),修复了一些小问题。最终这些JWT和API模块是要移除的,只保留采集模块,同时会增加写文件模块。

上级 d6645e73
流水线 #200 已失败 于阶段
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>fp-acq-wz</artifactId>
<groupId>com.zjty.fp</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>acq-jwt</artifactId>
<name>acq-jwt</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
</dependencies>
</project>
package com.zjty.fp.acq.jwt;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* JwtWebConfig.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2019-04-25 at 16:13
*/
@Configuration
@EnableWebSecurity
public class JwtWebConfig extends WebSecurityConfigurerAdapter {
// 设置 HTTP 验证规则
@Override
protected void configure(HttpSecurity http) throws Exception {
// 关闭csrf验证
http.cors().and().csrf().disable()
// 对请求进行认证
.authorizeRequests()
// 所有 / 的所有请求 都放行
.antMatchers("/").permitAll()
// 所有 /login 的POST请求 都放行
.antMatchers(HttpMethod.POST, "/api/token").permitAll()
// // 添加权限检测
// .antMatchers("/hello").hasAuthority("AUTH_WRITE")
// // 角色检测
// .antMatchers("/world").hasRole("ADMIN")
// 所有请求需要身份认证
.anyRequest().authenticated()
.and()
// 添加一个过滤器 所有访问 /login 的请求交给 JWTLoginFilter 来处理 这个类处理所有的JWT相关内容
.addFilterBefore(new com.zjty.fp.acq.jwt.JWTLoginFilter("/api/token", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// 添加一个过滤器验证其他请求的Token是否合法
.addFilterBefore(new com.zjty.fp.acq.jwt.JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
// 使用自定义身份验证组件
auth.authenticationProvider(new com.zjty.fp.acq.jwt.CustomAuthenticationProvider());
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class User {
private Long id;
private String username;
private String password;
}
/**
* 登录过滤器
*/
@SuppressWarnings("AlibabaClassNamingShouldBeCamel")
class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
public JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
/**
* 登录时会调用的服务
* 解析user对象并将其转为auth对象
*/
@Override
public Authentication attemptAuthentication(
HttpServletRequest req, HttpServletResponse res)
throws AuthenticationException, IOException {
// JSON反序列化成 user
com.zjty.fp.acq.jwt.User user = new ObjectMapper().readValue(req.getInputStream(), com.zjty.fp.acq.jwt.User.class);
// 返回一个验证令牌
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(
user.getUsername(),
user.getPassword()
)
);
}
/**
* 登录成功时会执行的逻辑
*/
@Override
protected void successfulAuthentication(
HttpServletRequest req,
HttpServletResponse res, FilterChain chain,
Authentication auth) {
com.zjty.fp.acq.jwt.TokenAuthenticationService.addAuthentication(res, auth.getName());
}
/**
* 登录失败会执行的逻辑
*/
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getOutputStream().println("登录失败,检查参数是否正确");
}
}
/**
* jwt验证过滤器,用于验证jwt是否合法
*/
class JWTAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
Authentication authentication = com.zjty.fp.acq.jwt.TokenAuthenticationService
.getAuthentication((HttpServletRequest) request);
SecurityContextHolder.getContext()
.setAuthentication(authentication);
filterChain.doFilter(request, response);
}
}
@Slf4j
class TokenAuthenticationService {
/**
* jwt失效时间 目前是10天
*/
static final long EXPIRATIONTIME = 864000000;
/**
* jwt 密码
*/
static final String SECRET = "P@ssw02d";
/**
* token 前缀
*/
static final String TOKEN_PREFIX = "Bearer";
/**
* 存放token的Header Key
*/
static final String HEADER_STRING = "Authorization";
static void addAuthentication(HttpServletResponse response, String username) {
long five_year_mills = LocalDateTime.now().plusYears(5L).toEpochSecond(ZoneOffset.of("+8"));
// 生成JWT
String JWT = Jwts.builder()
// 保存权限(角色)
.claim("authorities", "ROLE_ADMIN,AUTH_WRITE")
// 用户名写入标题
.setSubject(username)
//new Date(System.currentTimeMillis() + 3600000)
// 有效期设置
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
// 签名设置
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
log.info("jwt token 生成成功 token : {}", JWT);
// 将 JWT 写入 body
try {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
String token = new ObjectMapper().writeValueAsString(ImmutableMap.of("token", JWT));
response.getOutputStream().println(token);
} catch (IOException e) {
e.printStackTrace();
}
}
static Authentication getAuthentication(HttpServletRequest request) {
// 从Header中拿到token
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// 解析 Token
Claims claims = Jwts.parser()
// 验签
.setSigningKey(SECRET)
// 去掉 Bearer
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody();
// 拿用户名
String username = claims.getSubject();
// 得到 权限(角色)
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("authorities"));
// 返回验证令牌
return username != null ?
new UsernamePasswordAuthenticationToken(username, null, authorities) :
null;
}
return null;
}
}
// 自定义身份认证验证组件
class CustomAuthenticationProvider implements AuthenticationProvider {
private static final String TOKEN_USERNAME = "cdwa";
private static final String TOKEN_PASSWD = "P@ssw02d";
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// 获取认证的用户名 & 密码
String name = authentication.getName();
String password = authentication.getCredentials().toString();
// 认证逻辑
if (name.equals(TOKEN_USERNAME) && password.equals(TOKEN_PASSWD)) {
// 这里设置权限和角色
ArrayList<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
authorities.add(new SimpleGrantedAuthority("AUTH_WRITE"));
// 生成令牌
Authentication auth = new UsernamePasswordAuthenticationToken(name, password, authorities);
return auth;
} else {
throw new BadCredentialsException("密码错误~");
}
}
// 是否可以提供输入类型的认证服务
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
......@@ -6,7 +6,6 @@
<artifactId>fp-acq-wz</artifactId>
<groupId>com.zjty.fp</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -37,7 +37,7 @@ public class PsspInitialRunner {
return args -> {
log.info("[pssp] 正在尝试初始化 pssp 网站Map字段表");
//List<Website> -> key : id , value : Website
// List<Website> -> key : id , value : Website
Map<Long, Website> websiteMap = websiteService.findDictMap();
DictConst.WEBSITE_MAP = websiteMap;
......@@ -45,7 +45,7 @@ public class PsspInitialRunner {
log.info("[pssp] 正在尝试初始化 pssp 地区Map字段表");
//List<Website> -> key : code , value : Region
// List<Website> -> key : code , value : Region
Map<String, Region> regionMap = regionService.findDictMap();
DictConst.REGION_MAP = regionMap;
......
......@@ -51,12 +51,10 @@ public class PsspTestController {
}
/**
* 抓取所有网页数据(当前月)
* 抓取所有网页数据
*/
@GetMapping("/websites/all")
public ResponseEntity<String> fetchAllWebsites(
@RequestParam(value = "startTime") String startTime,
@RequestParam(value = "endTime") String endTime) {
public ResponseEntity<String> fetchAllWebsites() {
//抓取指定月份的数据
websiteService.fetchAllData();
return ResponseEntity.ok("fetch websites success");
......@@ -72,7 +70,7 @@ public class PsspTestController {
}
/**
* 抓取所有网页数据(当前月)
* 抓取所有区域数据
*/
@GetMapping("/regions/all")
public ResponseEntity<String> fetchAllRegions() {
......
......@@ -126,6 +126,12 @@ public class RemoteAlert {
@Column(name = "tm_confidential")
private Date tmConfidential;
@Column(name = "suspicious_remark")
private String susRemark;
@Column(name = "confidential_remark")
private String conRemark;
/**
* 数据是否为压缩类型
*/
......
......@@ -31,6 +31,14 @@ public class RemoteWebsite {
private String scope;
private String host;
private String domain;
private String contact;
private String phone;
private String unit;
private Integer codeOrg;
......@@ -46,6 +54,12 @@ public class RemoteWebsite {
private Integer statusCollect;
private Integer statusRun;
private Integer statusError;
private Integer idUser;
public Website toDo() {
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setAmbiguityIgnored(true);
......
......@@ -54,18 +54,23 @@ public class AlertServiceImpl implements AlertService {
public void fetchAllData() {
//遍历一个时间集合,用来抓取历史数据,获取当前月,添加今年一月至当前月的数据
List<LocalDate> monthTables = new ArrayList<>();
int nowYear = LocalDate.now().getYear();
int nowMonth = LocalDate.now().getMonthValue();
log.info("[pssp] [历史任务] 确认历史任务的采集月份范围");
for (int i = 1; i < nowMonth; i++) {
//check month
try {
remoteAlertRepo.count();
monthTables.add(LocalDate.of(nowYear, i, 1));
} catch (Exception e) {
log.warn("[pssp] [历史任务] 检测源目标数据库没有 {}-{}月表数据", nowYear, i);
}
}
//WZ项目 添加2017年12月 201801 202007 三个月的数据
monthTables.add(LocalDate.of(2017, 12, 1));
monthTables.add(LocalDate.of(2018, 1, 1));
// monthTables.add(LocalDate.of(2020, 7, 1));
// int nowYear = LocalDate.now().getYear();
// int nowMonth = LocalDate.now().getMonthValue();
// log.info("[pssp] [历史任务] 确认历史任务的采集月份范围");
// for (int i = 1; i < nowMonth; i++) {
// //check month
// try {
// remoteAlertRepo.count();
// monthTables.add(LocalDate.of(nowYear, i, 1));
// } catch (Exception e) {
// log.warn("[pssp] [历史任务] 检测源目标数据库没有 {}-{}月表数据", nowYear, i);
// }
// }
log.info("[pssp] [历史任务] 正在进行历史任务采集任务... 要采集的月份时间为{}", monthTables
.stream()
......
......@@ -76,8 +76,8 @@ public class CollectDataTask {
/**
* This method is for debug
*/
@EnablePsspSchProtect
@Scheduled(cron = "0 0/1 * * * ?")
// @EnablePsspSchProtect
// @Scheduled(cron = "0 0/1 * * * ?")
public void checkPsspDataCount() {
long simcCount = remotePsspRep.count();
long apiCount = localPsspRep.count();
......@@ -89,7 +89,7 @@ public class CollectDataTask {
* 抓取更新的网站的数据,当前为1h/次
*/
@EnablePsspSchProtect
@Scheduled(cron = "0 0 0/1 * * ?")
// @Scheduled(cron = "0 0 0/1 * * ?")
public void collectWebsiteData() {
log.info("[pssp] [定时任务]抓取更新的网站数据");
websiteService.fetchUpdatedData();
......@@ -99,7 +99,7 @@ public class CollectDataTask {
* 抓取更新的地区的数据,当前为1h/次
*/
@EnablePsspSchProtect
@Scheduled(cron = "0 0 0/1 * * ?")
// @Scheduled(cron = "0 0 0/1 * * ?")
public void collectRegionData() {
log.info("[pssp] [定时任务]抓取更新的区域数据");
regionService.fetchUpdatedData();
......@@ -109,7 +109,7 @@ public class CollectDataTask {
* 抓取更新的报警数据,当前为1min/次
*/
@EnablePsspSchProtect
@Scheduled(cron = "30 0/1 * * * ?")
// @Scheduled(cron = "30 0/1 * * * ?")
public void collectAlertData() {
log.info("[pssp] [定时任务] 抓取更新的报警数据");
alertService.fetchUpdatedData();
......@@ -120,9 +120,9 @@ public class CollectDataTask {
* <li>1.关闭其他计划任务</li>
* <li>2.将当前动态处理的表时间更改为上个月时间</li>
* <li>3.执行数据更新任务</li>
* <li4.更正时间,开启其他计划任务></li>
* <li>4.更正时间,开启其他计划任务></li>
*/
@Scheduled(cron = "0 10 0 1 * ?")
// @Scheduled(cron = "0 10 0 1 * ?")
@EnablePsspSchProtect
public void replenishMysqlDataMonthly() {
log.info("[pssp] [定时任务] 正在执行月末数据补偿任务,暂停其他计划任务,要补偿的月份数据是 {}", LocalDate.now().minusMonths(1L).toString());
......
......@@ -6,7 +6,6 @@
<artifactId>fp-acq-wz</artifactId>
<groupId>com.zjty.fp</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -77,6 +76,12 @@
<artifactId>acq-vomp</artifactId>
</dependency>
<dependency>
<groupId>com.zjty.fp</groupId>
<artifactId>acq-jwt</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
......
......@@ -19,6 +19,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
"com.zjty.fp.acq.pssp",
"com.zjty.fp.acq.vomp",
"com.zjty.fp.acq.misc",
"com.zjty.fp.acq.jwt"
})
@EnableScheduling
public class UnionApplication {
......
......@@ -119,6 +119,7 @@ public class DataSourceConfig {
*/
private TableRuleConfiguration getAlertTableRuleConfiguration() {
String actualDataNodes = "" +
"ds0.pssp_alert_201712," +
"ds0.pssp_alert_201807," +
"ds0.pssp_alert_201808," +
"ds0.pssp_alert_201809," +
......
# suppress inspection "SpringBootApplicationProperties" for whole file
spring.application.name=fp-api
spring.application.name=fp-acq-wz
# 数据库one相关配置 21.18.29.98:3306/db_secret_alert.
spring.datasource.remote.driver-class-name=com.mysql.jdbc.Driver
......@@ -30,7 +30,7 @@ spring.datasource.remote.test-while-idle=true
# 数据库two相关配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.location.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.location.url=jdbc:mysql://localhost:3306/fp_api?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
spring.datasource.location.url=jdbc:mysql://localhost:3306/fp_api_empty?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
spring.datasource.location.username=fp
spring.datasource.location.password=fp123456
## StatFilter
......@@ -58,6 +58,10 @@ spring.datasource.remote2.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.remote2.url=jdbc:mysql://localhost:3306/fp_simc?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
spring.datasource.remote2.username=fp
spring.datasource.remote2.password=fp123456
#spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
#spring.datasource.url=jdbc:sqlserver://21.28.120.2:1433;DatabaseName=PowerMonJava;
#spring.datasource.username=ms
#spring.datasource.password=ms123456
# ftp
ftp.server.ip=192.168.1.159
ftp.server.port=2121
......
# suppress inspection "SpringBootApplicationProperties" for whole file
spring.application.name=fp-api
spring.application.name=fp-acq-wz
# 数据库one相关配置 21.18.29.98:3306/db_secret_alert.
spring.datasource.remote.driver-class-name=com.mysql.jdbc.Driver
......
......@@ -6,7 +6,6 @@
<artifactId>fp-acq-wz</artifactId>
<groupId>com.zjty.fp</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -32,6 +31,12 @@
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
<!--动态查询-->
<dependency>
<groupId>com.github.wenhao</groupId>
......
......@@ -47,7 +47,7 @@ public class VompTasks {
/**
* 60分钟执行一次 读取
*/
@Scheduled(initialDelay = 4000, fixedRate = 60000 * 60)
// @Scheduled(initialDelay = 4000, fixedRate = 60000 * 60)
public void updateData() {
dataDbUpdater.updateData();
mapUpdater.updateData();
......@@ -56,7 +56,7 @@ public class VompTasks {
/**
* 3分钟执行一次
*/
@Scheduled(initialDelay = 4000, fixedRate = 60000 * 3)
// @Scheduled(initialDelay = 4000, fixedRate = 60000 * 3)
public void updateRedisData() {
log.info("[vomp] 开始更新缓存数据");
mapUpdater.updateData();
......
......@@ -29,6 +29,7 @@
<module>acq-vomp</module>
<module>acq-union</module>
<module>acq-misc</module>
<module>acq-jwt</module>
</modules>
<dependencyManagement>
......@@ -57,6 +58,12 @@
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.zjty.fp</groupId>
<artifactId>acq-jwt</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论