From 039f39d787cf9b2346ae3085f19e866243660e1a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E5=88=98=E6=B4=AA=E9=9D=92?= Date: Mon, 2 Sep 2019 12:08:57 +0800 Subject: [PATCH] =?utf8?q?feat:=20=E5=A4=84=E7=90=86Basic=E8=AE=A4?= =?utf8?q?=E8=AF=81=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- bff/admin/pom.xml | 19 +++-- .../BasicWebFluxSecurityConfiguration.java | 34 ++++++++ .../basic/EnableInfrasBasicWebFluxApi.java | 17 ++++ .../backend/admin/bff/Application.java | 80 +++++++++++++------ ...InfrasFilterSecurityInterceptorConfig.java | 20 ++--- .../MyFilterSecurityInterceptor.java | 78 ------------------ pom.xml | 2 +- 7 files changed, 130 insertions(+), 120 deletions(-) create mode 100644 bff/admin/src/main/java/com/supwisdom/infras/security/reactive/basic/BasicWebFluxSecurityConfiguration.java create mode 100644 bff/admin/src/main/java/com/supwisdom/infras/security/reactive/basic/EnableInfrasBasicWebFluxApi.java delete mode 100644 bff/admin/src/main/java/com/supwisdom/institute/backend/admin/bff/security/web/access/intercept/MyFilterSecurityInterceptor.java 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 @@ spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-starter-openfeign - - - org.springframework.boot spring-boot-starter-webflux @@ -65,6 +58,11 @@ spring-cloud-starter-gateway + + org.springframework.cloud + spring-cloud-starter-openfeign + + - + + + + org.springframework.boot + spring-boot-starter-security 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.boot.autoconfigure.SpringBootApplication; 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 @@ import com.supwisdom.institute.backend.common.framework.exception.EnableCustomEx //@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.context.annotation.Configuration; 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 @@ public class InfrasFilterSecurityInterceptorConfig { 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 noneSecurityUrl = new HashSet(); // 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; - } - -} diff --git a/pom.xml b/pom.xml index af472b8..26ca59e 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ harbor.supwisdom.com sw-backend - 0.1.0-SNAPSHOT + 0.1.1-SNAPSHOT 2.9.2 -- 2.17.1