Commit 6da4438a by 阳浪

解决安全漏扫问题

parent 849036a0
...@@ -72,7 +72,10 @@ ...@@ -72,7 +72,10 @@
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
<version>3.3.0</version> <version>3.3.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.hibernate.validator</groupId> <groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId> <artifactId>hibernate-validator</artifactId>
......
package com.yizhi.core.application.security.config;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import com.yizhi.core.application.cache.RedisCache;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
/**
* 未认证用户访问须授权资源端点
*
* @author xuyuxiang
* @date 2020/3/18 11:52
*/
@Component
@Slf4j
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
@Autowired
private RedisCache redisCache;
private String WHITE_KEY ="system:url:whitelist";
/**
* 访问未经授权的接口时执行此方法,未经授权的接口包含系统中存在和不存在的接口,分别处理
*
* @author xuyuxiang
* @date 2020/3/18 19:15
*/
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
String requestUri = request.getRequestURI();
RequestContext context = ContextHolder.get();
List<String> uriList = Lists.newArrayList();
Object whiteObject = redisCache.get(WHITE_KEY);
if(whiteObject!=null){
uriList = JSONArray.parseArray(whiteObject.toString(),String.class);
}else{
uriList.add("/web-manage/*");
uriList.add("/web-student/*");
uriList.add("/system/*");
uriList.add("/training/*");
uriList.add("/exam/*");
uriList.add("/sign/*");
uriList.add("/site/*");
uriList.add("/research/*");
uriList.add("/newMessage/*");
uriList.add("/job/*");
uriList.add("/enroll/*");
uriList.add("/drools/*");
uriList.add("/log/*");
uriList.add("/assignment/*");
uriList.add("/album/*");
uriList.add("/aliyun/*");
uriList.add("/caselibrary/*");
uriList.add("/forum/*");
uriList.add("/cloud-xxl-job-executor/*");
uriList.add("/cloud-xxl-job-admin/*");
uriList.add("/comment/*");
uriList.add("/course/*");
uriList.add("/point/*");
redisCache.set(WHITE_KEY,JSONArray.toJSONString(uriList));
}
if(CollectionUtil.isNotEmpty(uriList)) {
Optional<String> optional = uriList.stream().filter(u -> isMatch(u, requestUri)).findFirst();
if(optional!=null&&optional.isPresent()){
return;
}
}
//校验用户登录
if (ObjectUtil.isEmpty(context)||ObjectUtil.isEmpty(context.getAccountId())) {
log.error(">>> 用户未登录或登录已过期,requestUri={}", requestUri);
throw new RuntimeException("用户未登录或登录已过期");
}
}
public boolean isMatch(String pattern, String text) {
String regexPattern = pattern.replace(".", "\\.").replace("*", ".*");
return java.util.regex.Pattern.matches(regexPattern, text);
}
}
package com.yizhi.core.application.security.config;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import javax.annotation.Resource;
/**
* SpringSecurity配置
* @author xuyuxiang
* @date 2020/3/18 10:54
*/
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
//开启模拟请求,比如API POST测试工具的测试,不开启时,API POST为报403错误
httpSecurity.csrf().disable();
//开启跨域访问
// httpSecurity.cors();
//不使用默认退出,自定义退出
httpSecurity.logout().disable();
//未授权时访问须授权的资源端点
httpSecurity.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint);
//其余的都需授权访问
httpSecurity.authorizeRequests().anyRequest().authenticated();
//全局不创建session
// httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
//禁用页面缓存,返回的都是json
httpSecurity.headers()
.frameOptions().disable()
.cacheControl();
}
}
...@@ -7,4 +7,12 @@ spring.cloud.nacos.config.shared-dataids=common-${spring.profiles.active}.proper ...@@ -7,4 +7,12 @@ spring.cloud.nacos.config.shared-dataids=common-${spring.profiles.active}.proper
spring.cloud.nacos.config.namespace=${spring.profiles.active} spring.cloud.nacos.config.namespace=${spring.profiles.active}
spring.cloud.nacos.config.prefix=${spring.application.name} spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=properties spring.cloud.nacos.config.file-extension=properties
spring.cloud.nacos.config.server-addr=10.23.1.183:8848 spring.cloud.nacos.config.server-addr=10.23.1.183:8848
\ No newline at end of file
# ssl
server.ssl.enabled=false
server.ssl.key-store=classpath:shanghaiairport.com.jks
server.ssl.key-store-password=now0jsve
server.ssl.protocol=TLSv1
server.ssl.key-store-type=JKS
\ No newline at end of file
package com.yizhi.application; package com.yizhi.application;
import com.yizhi.core.application.log.LogQueue; import com.yizhi.core.application.log.LogQueue;
import com.yizhi.core.application.security.config.SpringSecurityConfig;
import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.Queue;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
...@@ -8,6 +9,7 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; ...@@ -8,6 +9,7 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.DependsOn;
@SpringBootApplication(exclude = {RabbitAutoConfiguration.class}) @SpringBootApplication(exclude = {RabbitAutoConfiguration.class})
...@@ -38,6 +40,10 @@ public class LogApplication { ...@@ -38,6 +40,10 @@ public class LogApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(LogApplication.class, args); SpringApplication.run(LogApplication.class, args);
} }
@Bean
public SpringSecurityConfig springSecurityConfig(){
return new SpringSecurityConfig();
}
} }
...@@ -11,11 +11,15 @@ import org.springframework.http.ResponseEntity; ...@@ -11,11 +11,15 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo; import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Collections;
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2
public class SwaggerConfig { public class SwaggerConfig {
...@@ -34,7 +38,21 @@ public class SwaggerConfig { ...@@ -34,7 +38,21 @@ public class SwaggerConfig {
.select() .select()
.paths(or(regex("/api.*"),regex("/manage.*"),regex("/remote.*"))) .paths(or(regex("/api.*"),regex("/manage.*"),regex("/remote.*")))
.build() .build()
.apiInfo(apiInfo()); .apiInfo(apiInfo())
.securitySchemes(Collections.singletonList(securitySchema()))
.securityContexts(Collections.singletonList(securityContext()));
}
private SecurityScheme securitySchema() {
return new BasicAuth("BasicAuth");
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(Collections.singletonList(
new SecurityReference("BasicAuth", new AuthorizationScope[] {new AuthorizationScope("global", "accessAll")})))
.forPaths(PathSelectors.any())
.build();
} }
private ApiInfo apiInfo() { private ApiInfo apiInfo() {
......
...@@ -11,11 +11,15 @@ import org.springframework.http.ResponseEntity; ...@@ -11,11 +11,15 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo; import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Collections;
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2
public class SwaggerConfig { public class SwaggerConfig {
...@@ -34,7 +38,21 @@ public class SwaggerConfig { ...@@ -34,7 +38,21 @@ public class SwaggerConfig {
.select() .select()
.paths(or(regex("/api.*"),regex("/manage.*"),regex("/remote.*"))) .paths(or(regex("/api.*"),regex("/manage.*"),regex("/remote.*")))
.build() .build()
.apiInfo(apiInfo()); .apiInfo(apiInfo())
.securitySchemes(Collections.singletonList(securitySchema()))
.securityContexts(Collections.singletonList(securityContext()));
}
private SecurityScheme securitySchema() {
return new BasicAuth("BasicAuth");
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(Collections.singletonList(
new SecurityReference("BasicAuth", new AuthorizationScope[] {new AuthorizationScope("global", "accessAll")})))
.forPaths(PathSelectors.any())
.build();
} }
private ApiInfo apiInfo() { private ApiInfo apiInfo() {
......
package com.yizhi.system.application; import feign.RequestInterceptor;import feign.RequestTemplate;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.hystrix.EnableHystrix;import org.springframework.cloud.openfeign.EnableFeignClients;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.core.env.Environment;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.Enumeration; @EnableHystrix@SpringBootApplication(exclude = {RabbitAutoConfiguration.class})@EnableDiscoveryClient@EnableFeignClients(basePackages = "com.yizhi")@EnableAsync@ComponentScan(basePackages = {"com.yizhi"})public class SystemApplication { private static final Logger logger = LoggerFactory.getLogger(SystemApplication.class); public static void main(String[] args) throws UnknownHostException { Environment env = SpringApplication.run(SystemApplication.class, args).getEnvironment(); String port = env.getProperty("server.port", "8080"); logger.info( "Access URLs:\n----------------------------------------------------------\n\t" + "Local: \t\thttp://10.23.1.183:{}\n\t" + "External: \thttp://{}:{}\n----------------------------------------------------------", port, InetAddress.getLocalHost().getHostAddress(), port); } @Bean //帮助调其他服务时,能取到上下文里面的信息 public RequestInterceptor headerInterceptor() { return new RequestInterceptor() { @Override public void apply(RequestTemplate requestTemplate) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder .getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); Enumeration<String> headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); String values = request.getHeader(name); requestTemplate.header(name, values); } } } } }; } } package com.yizhi.system.application; import com.yizhi.core.application.security.config.SpringSecurityConfig;import feign.RequestInterceptor;import feign.RequestTemplate;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.hystrix.EnableHystrix;import org.springframework.cloud.openfeign.EnableFeignClients;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.DependsOn;import org.springframework.core.env.Environment;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.Enumeration; @EnableHystrix@SpringBootApplication(exclude = {RabbitAutoConfiguration.class})@EnableDiscoveryClient@EnableFeignClients(basePackages = "com.yizhi")@EnableAsync@ComponentScan(basePackages = {"com.yizhi"})public class SystemApplication { private static final Logger logger = LoggerFactory.getLogger(SystemApplication.class); public static void main(String[] args) throws UnknownHostException { Environment env = SpringApplication.run(SystemApplication.class, args).getEnvironment(); String port = env.getProperty("server.port", "8080"); logger.info( "Access URLs:\n----------------------------------------------------------\n\t" + "Local: \t\thttp://10.23.1.183:{}\n\t" + "External: \thttp://{}:{}\n----------------------------------------------------------", port, InetAddress.getLocalHost().getHostAddress(), port); } @Bean public SpringSecurityConfig springSecurityConfig(){ return new SpringSecurityConfig(); } @Bean //帮助调其他服务时,能取到上下文里面的信息 public RequestInterceptor headerInterceptor() { return new RequestInterceptor() { @Override public void apply(RequestTemplate requestTemplate) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder .getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); Enumeration<String> headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); String values = request.getHeader(name); requestTemplate.header(name, values); } } } } }; } }
\ No newline at end of file \ No newline at end of file
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment