feat: 处理Basic认证配置
diff --git a/bff/admin/pom.xml b/bff/admin/pom.xml
index ecd5261..fc19506 100644
--- a/bff/admin/pom.xml
+++ b/bff/admin/pom.xml
@@ -48,13 +48,6 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
-
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
-
-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
@@ -65,6 +58,11 @@
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-starter-openfeign</artifactId>
+ </dependency>
+
<!-- <dependency>
<groupId>com.supwisdom.infras</groupId>
@@ -93,7 +91,7 @@
</dependency> -->
- <dependency>
+ <!-- <dependency>
<groupId>com.supwisdom.infras</groupId>
<artifactId>infras-security</artifactId>
<exclusions>
@@ -102,6 +100,11 @@
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
</exclusions>
+ </dependency> -->
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
diff --git a/bff/admin/src/main/java/com/supwisdom/infras/security/reactive/basic/BasicWebFluxSecurityConfiguration.java b/bff/admin/src/main/java/com/supwisdom/infras/security/reactive/basic/BasicWebFluxSecurityConfiguration.java
new file mode 100644
index 0000000..6d71175
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/infras/security/reactive/basic/BasicWebFluxSecurityConfiguration.java
@@ -0,0 +1,34 @@
+package com.supwisdom.infras.security.reactive.basic;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.web.server.ServerHttpSecurity;
+import org.springframework.security.web.server.SecurityWebFilterChain;
+
+@Configuration
+@ConditionalOnProperty(name="infras.security.basic.enabled", havingValue="true")
+public class BasicWebFluxSecurityConfiguration {
+
+ @Bean
+ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
+ http
+ .authorizeExchange()
+ .pathMatchers(HttpMethod.OPTIONS).permitAll()
+ .pathMatchers("/api/public/**", "/api/open/**").permitAll()
+ .pathMatchers("/api/v*/public/**", "/api/v*/open/**").permitAll()
+ .pathMatchers("/api/*/v*/public/**", "/api/*/v*/open/**").permitAll()
+ .pathMatchers("/api/**").authenticated()
+ .anyExchange().authenticated();
+
+ http.httpBasic();
+
+ http.csrf().disable();
+
+ http.formLogin().disable();
+
+ return http.build();
+ }
+
+}
diff --git a/bff/admin/src/main/java/com/supwisdom/infras/security/reactive/basic/EnableInfrasBasicWebFluxApi.java b/bff/admin/src/main/java/com/supwisdom/infras/security/reactive/basic/EnableInfrasBasicWebFluxApi.java
new file mode 100644
index 0000000..9658d27
--- /dev/null
+++ b/bff/admin/src/main/java/com/supwisdom/infras/security/reactive/basic/EnableInfrasBasicWebFluxApi.java
@@ -0,0 +1,17 @@
+package com.supwisdom.infras.security.reactive.basic;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Import;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Import(BasicWebFluxSecurityConfiguration.class)
+public @interface EnableInfrasBasicWebFluxApi {
+
+}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java
index 942b082..bde129e 100644
--- a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java
@@ -5,19 +5,24 @@
import org.springframework.cloud.openfeign.EnableFeignClients;
//import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.cors.reactive.CorsUtils;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
-
-//import com.supwisdom.infras.online.doc.configuration.EnableInfrasOnlineDoc;
-import com.supwisdom.infras.security.configure.basic.EnableInfrasBasicApi;
-import com.supwisdom.infras.security.configure.cas.EnableInfrasCasSecurity;
-import com.supwisdom.infras.security.configure.jwt.EnableInfrasJWTApi;
+import com.supwisdom.infras.security.reactive.basic.EnableInfrasBasicWebFluxApi;
import com.supwisdom.institute.backend.common.core.transmit.annotation.EnableSimpleUserTransmit;
import com.supwisdom.institute.backend.common.framework.exception.EnableCustomExceptionHandler;
+import static org.springframework.web.cors.CorsConfiguration.ALL;
+
@SpringBootApplication
@EnableFeignClients
@@ -26,29 +31,58 @@
//@EnableInfrasOnlineDoc
-@EnableInfrasCasSecurity
+//@EnableInfrasCasSecurity
-@EnableInfrasBasicApi
-@EnableInfrasJWTApi
+//@EnableInfrasBasicApi
+//@EnableInfrasJWTApi
+
+@EnableInfrasBasicWebFluxApi
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
+// @Bean
+// public CorsFilter corsFilter() {
+// final CorsConfiguration config = new CorsConfiguration();
+// //config.setAllowCredentials(true);
+// config.addAllowedOrigin("*");
+// config.addAllowedHeader("*");
+// config.addAllowedMethod("*");
+//
+// final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+// source.registerCorsConfiguration("/v2/api-docs", config);
+// source.registerCorsConfiguration("/api/**", config); // 对 /api/** 下的请求,支持 cors 跨域请求,如不需要可以注释
+//
+// return new CorsFilter(source);
+// }
+
@Bean
- public CorsFilter corsFilter() {
- final CorsConfiguration config = new CorsConfiguration();
- //config.setAllowCredentials(true);
- config.addAllowedOrigin("*");
- config.addAllowedHeader("*");
- config.addAllowedMethod("*");
-
- final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
- source.registerCorsConfiguration("/v2/api-docs", config);
- source.registerCorsConfiguration("/api/**", config); // 对 /api/** 下的请求,支持 cors 跨域请求,如不需要可以注释
-
- return new CorsFilter(source);
+ public WebFilter corsFilter() {
+ return (ServerWebExchange ctx, WebFilterChain chain) -> {
+ ServerHttpRequest request = ctx.getRequest();
+ if (!CorsUtils.isCorsRequest(request)) {
+ return chain.filter(ctx);
+ }
+ HttpHeaders requestHeaders = request.getHeaders();
+ ServerHttpResponse response = ctx.getResponse();
+ HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
+ HttpHeaders headers = response.getHeaders();
+ headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
+ headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
+ if (requestMethod != null) {
+ headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
+ }
+ headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
+ headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, ALL);
+ // headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
+ if (request.getMethod() == HttpMethod.OPTIONS) {
+ response.setStatusCode(HttpStatus.OK);
+ return Mono.empty();
+ }
+ return chain.filter(ctx);
+ };
}
}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/InfrasFilterSecurityInterceptorConfig.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/InfrasFilterSecurityInterceptorConfig.java
index 6c77526..10410c9 100644
--- a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/InfrasFilterSecurityInterceptorConfig.java
+++ b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/InfrasFilterSecurityInterceptorConfig.java
@@ -5,10 +5,10 @@
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
-import com.supwisdom.infras.security.web.access.intercept.InfrasFilterSecurityInterceptor;
+//import com.supwisdom.infras.security.web.access.intercept.InfrasFilterSecurityInterceptor;
import com.supwisdom.institute.backend.admin.bff.security.web.access.MyAccessDecisionManager;
import com.supwisdom.institute.backend.admin.bff.security.web.access.intercept.InMemeryFilterInvocationSecurityMetadataSource;
-import com.supwisdom.institute.backend.admin.bff.security.web.access.intercept.MyFilterSecurityInterceptor;
+//import com.supwisdom.institute.backend.admin.bff.security.web.access.intercept.MyFilterSecurityInterceptor;
import lombok.extern.slf4j.Slf4j;
@@ -41,13 +41,13 @@
return accessDecisionManager;
}
- @Bean
- public InfrasFilterSecurityInterceptor infrasFilterSecurityInterceptor() throws Exception {
- MyFilterSecurityInterceptor myFilterSecurityInterceptor = new MyFilterSecurityInterceptor();
- myFilterSecurityInterceptor.setRejectPublicInvocations(true);
- log.debug("InfrasFilterSecurityInterceptorConfig infrasFilterSecurityInterceptor is {}", myFilterSecurityInterceptor);
-
- return myFilterSecurityInterceptor;
- }
+// @Bean
+// public InfrasFilterSecurityInterceptor infrasFilterSecurityInterceptor() throws Exception {
+// MyFilterSecurityInterceptor myFilterSecurityInterceptor = new MyFilterSecurityInterceptor();
+// myFilterSecurityInterceptor.setRejectPublicInvocations(true);
+// log.debug("InfrasFilterSecurityInterceptorConfig infrasFilterSecurityInterceptor is {}", myFilterSecurityInterceptor);
+//
+// return myFilterSecurityInterceptor;
+// }
}
diff --git a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterSecurityInterceptor.java b/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterSecurityInterceptor.java
deleted file mode 100644
index 7cd74e2..0000000
--- a/bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterSecurityInterceptor.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.supwisdom.institute.backend.admin.bff.security.web.access.intercept;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.servlet.ServletException;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.AccessDecisionManager;
-import org.springframework.security.access.SecurityMetadataSource;
-import org.springframework.security.access.intercept.InterceptorStatusToken;
-import org.springframework.security.web.FilterInvocation;
-import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
-
-import com.supwisdom.infras.security.web.access.intercept.InfrasFilterSecurityInterceptor;
-import com.supwisdom.institute.backend.admin.bff.utils.AuthenticationUtil;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public class MyFilterSecurityInterceptor extends InfrasFilterSecurityInterceptor {
-
- @Autowired
- private FilterInvocationSecurityMetadataSource securityMetadataSource;
-
- @Autowired
- public void setAccessDecisionManager(AccessDecisionManager accessDecisionManager) {
-
- super.setAccessDecisionManager(accessDecisionManager);
- }
-
- @Override
- public void invoke(FilterInvocation fi) throws IOException, ServletException {
-
- Set<String> noneSecurityUrl = new HashSet<String>(); // FIXME: 对无须访问控制的url,支持可配置
- noneSecurityUrl.add("/web/login");
- noneSecurityUrl.add("/web/logout");
- noneSecurityUrl.add("/web/index");
-
- if (fi.getRequest() != null) {
- String requestUrl = fi.getRequestUrl(); log.debug("MyFilterSecurityInterceptor invoke requestUrl: {}", requestUrl);
- if (noneSecurityUrl.contains(requestUrl)) {
- fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
- return;
- }
- }
-
- if(AuthenticationUtil.isAdministrator()){
- fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
- return;
- }
-
- // fi里面有一个被拦截的url
- // 里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
- // 再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
- InterceptorStatusToken token = super.beforeInvocation(fi);
- try {
- // 执行下一个拦截器
- fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
- } finally {
- super.afterInvocation(token, null);
- }
- }
-
- @Override
- public Class<?> getSecureObjectClass() {
-
- return FilterInvocation.class;
- }
-
- @Override
- public SecurityMetadataSource obtainSecurityMetadataSource() {
-
- return this.securityMetadataSource;
- }
-
-}