├── LICENSE ├── README.md ├── dubbo-gateway-api ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── atommiddleware │ └── cloud │ └── api │ └── annotation │ ├── FromAttribute.java │ ├── FromBody.java │ ├── FromCookie.java │ ├── FromHeader.java │ ├── FromPath.java │ ├── FromQueryParams.java │ ├── GateWayDubbo.java │ ├── ParamAttribute.java │ ├── ParamFormatConstants.java │ └── PathMapping.java ├── dubbo-gateway-core ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── atommiddleware │ │ └── cloud │ │ └── core │ │ ├── annotation │ │ ├── AbstractBaseApiWrapper.java │ │ ├── AbstractDubboApiServletWrapper.java │ │ ├── AbstractDubboApiWrapper.java │ │ ├── AbstractDubboApiWrapperFactory.java │ │ ├── BaseApiWrapper.java │ │ ├── DefaultDubboApiWrapperFactory.java │ │ ├── DefaultResponseResult.java │ │ ├── DefaultResponseServletResult.java │ │ ├── DefaultResponseZuulServletResult.java │ │ ├── DubboApiServletWrapper.java │ │ ├── DubboApiWrapper.java │ │ ├── DubboApiWrapperFactory.java │ │ ├── DubboGateWayApplicationListener.java │ │ ├── DubboGatewayImportBeanDefinitionRegistrar.java │ │ ├── DubboGatewayPostProcessor.java │ │ ├── DubboGatewayScanner.java │ │ ├── ParamInfo.java │ │ ├── ParamMeta.java │ │ ├── PathMappingMethodInfo.java │ │ ├── ResponseReactiveResult.java │ │ ├── ResponseServletResult.java │ │ └── ResponseZuulServletResult.java │ │ ├── cas │ │ └── CasAjaxAuthenticationEntryPoint.java │ │ ├── config │ │ ├── DubboReferenceConfig.java │ │ ├── DubboReferenceConfigProperties.java │ │ └── ReferenceMethodConfig.java │ │ ├── context │ │ └── DubboApiContext.java │ │ ├── controller │ │ └── ForwardingServiceController.java │ │ ├── dubbo │ │ └── filter │ │ │ └── UserFilter.java │ │ ├── exception │ │ └── JsonExceptionHandler.java │ │ ├── filter │ │ ├── DubboGlobalFilter.java │ │ ├── DubboServletFilter.java │ │ ├── DubboServletZuulFilter.java │ │ ├── ServletErrorFilter.java │ │ └── ZuulErrorFilter.java │ │ ├── security │ │ ├── DefaultPrincipalObtain.java │ │ ├── DefaultXssSecurity.java │ │ ├── EncodeHtmlXssSecurity.java │ │ ├── EsapiEncodeHtmlXssSecurity.java │ │ └── XssSecurity.java │ │ ├── serialize │ │ ├── CustomXssObjectMapper.java │ │ ├── JacksonSerialization.java │ │ └── Serialization.java │ │ └── utils │ │ └── HttpUtils.java │ └── resources │ ├── META-INF │ └── dubbo │ │ └── org.apache.dubbo.rpc.Filter │ └── esapi │ ├── ESAPI.properties │ └── validation.properties ├── dubbo-gateway-parent └── pom.xml ├── dubbo-gateway-sample-api ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── atommiddleware │ └── cloud │ └── sample │ └── api │ ├── Result.java │ ├── order │ ├── OrderQuery.java │ ├── OrderService.java │ └── domain │ │ └── Order.java │ └── user │ ├── UserService.java │ └── domain │ └── User.java ├── dubbo-gateway-sample-provider ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── atommiddleware │ │ └── cloud │ │ └── sample │ │ └── provider │ │ ├── App.java │ │ ├── order │ │ ├── OrderQueryImpl.java │ │ └── OrderServiceImpl.java │ │ └── user │ │ └── UserServiceImpl.java │ └── resources │ └── bootstrap.yml ├── dubbo-gateway-sample-web-consumer ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── atommiddleware │ │ └── sample │ │ └── web │ │ └── consumer │ │ └── App.java │ └── resources │ └── application.yml ├── dubbo-gateway-sample-web-provider ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── atommiddleware │ │ └── sample │ │ └── web │ │ └── provider │ │ ├── App.java │ │ ├── controller │ │ └── HelloWorldController.java │ │ ├── order │ │ ├── OrderQueryImpl.java │ │ └── OrderServiceImpl.java │ │ └── user │ │ └── UserServiceImpl.java │ └── resources │ └── application.yml ├── dubbo-gateway-sample-zuul ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── atommiddleware │ │ └── cloud │ │ └── zuul │ │ └── App.java │ └── resources │ ├── bootstrap.yml │ └── static │ └── favicon.ico ├── dubbo-gateway-sample ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── atommiddleware │ │ └── cloud │ │ └── sample │ │ └── App.java │ └── resources │ └── bootstrap.yml ├── dubbo-gateway-security ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── atommiddleware │ └── cloud │ └── security │ ├── cas │ ├── BasedVoter.java │ ├── CustomUserDetailsService.java │ ├── PathPatternGrantedAuthority.java │ └── PrincipalObtain.java │ ├── utils │ └── ValidatorUtils.java │ └── validation │ ├── DefaultParamValidator.java │ └── ParamValidator.java ├── dubbo-gateway-spring-boot-autoconfigure ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── atommiddleware │ │ └── cloud │ │ └── autoconfigure │ │ ├── CasSecurityAutoConfiguration.java │ │ ├── CasSecurityWebSecurityConfigurerAdapterAutoConfiguration.java │ │ ├── DubboGateWayApplicationContextInitializer.java │ │ ├── DubboGatewayAutoConfiguration.java │ │ ├── DubboGatewayBootstrapConfiguration.java │ │ ├── DubboGatewayCommonAutoConfiguration.java │ │ ├── DubboGatewayServletAutoConfiguration.java │ │ ├── DubboGatewayZuulServletAutoConfiguration.java │ │ ├── ExceptionHandlerConfiguration.java │ │ ├── RedisHttpSessionAutoConfiguration.java │ │ └── SevlertImportBeanDefinitionRegistrar.java │ └── resources │ └── META-INF │ ├── spring-autoconfigure-metadata.properties │ └── spring.factories ├── dubbo-gateway-spring-boot-starter └── pom.xml ├── dubboGateWay.postman_collection.json └── dubboGateWay_XSS.postman_collection.json /dubbo-gateway-api/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.atommiddleware 7 | dubbo-gateway-parent 8 | ${revision} 9 | ../dubbo-gateway-parent/pom.xml 10 | 11 | jar 12 | dubbo-gateway-api 13 | ${project.artifactId} 14 | The api module of dubbo gateway 15 | 16 | 17 | 18 | org.springframework 19 | spring-core 20 | true 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/FromAttribute.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 12 | 13 | @Target(ElementType.PARAMETER) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Documented 16 | @ParamAttribute(paramFromType = ParamFromType.FROM_ATTRIBUTE) 17 | public @interface FromAttribute { 18 | 19 | @AliasFor(annotation = ParamAttribute.class) 20 | String value() default ""; 21 | 22 | @AliasFor(annotation = ParamAttribute.class) 23 | String name() default ""; 24 | 25 | @AliasFor(annotation = ParamAttribute.class) 26 | boolean required() default true; 27 | } 28 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/FromBody.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 12 | 13 | @Target(ElementType.PARAMETER) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Documented 16 | @ParamAttribute(paramFromType = ParamFromType.FROM_BODY) 17 | public @interface FromBody { 18 | 19 | @AliasFor(annotation = ParamAttribute.class) 20 | boolean required() default true; 21 | } 22 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/FromCookie.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFormat; 12 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 13 | 14 | @Target(ElementType.PARAMETER) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Documented 17 | @ParamAttribute(paramFromType = ParamFromType.FROM_COOKIE) 18 | public @interface FromCookie { 19 | 20 | @AliasFor(annotation = ParamAttribute.class) 21 | String value() default ""; 22 | 23 | @AliasFor(annotation = ParamAttribute.class) 24 | String name() default ""; 25 | 26 | @AliasFor(annotation = ParamAttribute.class) 27 | boolean required() default true; 28 | 29 | @AliasFor(annotation = ParamAttribute.class) 30 | ParamFormat paramFormat() default ParamFormat.MAP; 31 | } 32 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/FromHeader.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFormat; 12 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 13 | 14 | @Target(ElementType.PARAMETER) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Documented 17 | @ParamAttribute(paramFromType = ParamFromType.FROM_HEADER) 18 | public @interface FromHeader { 19 | 20 | @AliasFor(annotation = ParamAttribute.class) 21 | String value() default ""; 22 | 23 | @AliasFor(annotation = ParamAttribute.class) 24 | String name() default ""; 25 | 26 | @AliasFor(annotation = ParamAttribute.class) 27 | boolean required() default true; 28 | 29 | @AliasFor(annotation = ParamAttribute.class) 30 | ParamFormat paramFormat() default ParamFormat.MAP; 31 | } 32 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/FromPath.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFormat; 12 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 13 | 14 | @Target(ElementType.PARAMETER) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Documented 17 | @ParamAttribute(paramFromType = ParamFromType.FROM_PATH) 18 | public @interface FromPath { 19 | 20 | @AliasFor(annotation = ParamAttribute.class) 21 | String value() default ""; 22 | 23 | @AliasFor(annotation = ParamAttribute.class) 24 | String name() default ""; 25 | 26 | @AliasFor(annotation = ParamAttribute.class) 27 | boolean required() default true; 28 | 29 | @AliasFor(annotation = ParamAttribute.class) 30 | ParamFormat paramFormat() default ParamFormat.MAP; 31 | } 32 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/FromQueryParams.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFormat; 12 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 13 | 14 | @Target(ElementType.PARAMETER) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Documented 17 | @ParamAttribute(paramFromType = ParamFromType.FROM_QUERYPARAMS) 18 | public @interface FromQueryParams { 19 | 20 | @AliasFor(annotation = ParamAttribute.class) 21 | String value() default ""; 22 | 23 | @AliasFor(annotation = ParamAttribute.class) 24 | String name() default ""; 25 | 26 | @AliasFor(annotation = ParamAttribute.class) 27 | boolean required() default true; 28 | 29 | @AliasFor(annotation = ParamAttribute.class) 30 | ParamFormat paramFormat() default ParamFormat.MAP; 31 | } 32 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/GateWayDubbo.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | @Target(ElementType.TYPE) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface GateWayDubbo { 15 | 16 | @AliasFor("id") 17 | String value() default ""; 18 | 19 | @AliasFor("value") 20 | String id() default ""; 21 | } 22 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/ParamAttribute.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | @Target(ElementType.ANNOTATION_TYPE) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface ParamAttribute { 15 | 16 | @AliasFor("name") 17 | String value() default ""; 18 | 19 | @AliasFor("value") 20 | String name() default ""; 21 | 22 | boolean required() default true; 23 | 24 | ParamFromType paramFromType(); 25 | 26 | ParamFormat paramFormat() default ParamFormat.MAP; 27 | 28 | public enum ParamFormat { 29 | MAP, JSON 30 | } 31 | public enum ParamFromType { 32 | FROM_BODY, FROM_COOKIE, FROM_HEADER, FROM_PATH, FROM_ATTRIBUTE, FROM_QUERYPARAMS; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/ParamFormatConstants.java: -------------------------------------------------------------------------------- 1 | //package com.atommiddleware.cloud.api.annotation; 2 | // 3 | //public class ParamFormatConstants { 4 | // 5 | // public static final int MAP=0; 6 | // 7 | // public static final int JSON=1; 8 | //} 9 | -------------------------------------------------------------------------------- /dubbo-gateway-api/src/main/java/com/atommiddleware/cloud/api/annotation/PathMapping.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.api.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.core.annotation.AliasFor; 10 | 11 | @Target(ElementType.METHOD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface PathMapping { 15 | 16 | @AliasFor("path") 17 | String value() default ""; 18 | 19 | @AliasFor("value") 20 | String path() default ""; 21 | 22 | RequestMethod requestMethod() default RequestMethod.POST; 23 | 24 | public enum RequestMethod { 25 | GET, POST 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dubbo-gateway-core/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | com.atommiddleware 8 | dubbo-gateway-parent 9 | ${revision} 10 | ../dubbo-gateway-parent/pom.xml 11 | 12 | jar 13 | dubbo-gateway-core 14 | ${project.artifactId} 15 | The core module of dubbo gateway 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-webflux 21 | true 22 | 23 | 24 | com.alibaba.cloud 25 | spring-cloud-starter-dubbo 26 | true 27 | 28 | 29 | com.atommiddleware 30 | dubbo-gateway-api 31 | ${project.parent.version} 32 | 33 | 34 | com.atommiddleware 35 | dubbo-gateway-security 36 | ${project.parent.version} 37 | 38 | 39 | org.projectlombok 40 | lombok 41 | provided 42 | 43 | 44 | javax.servlet 45 | javax.servlet-api 46 | provided 47 | 48 | 49 | org.springframework.cloud 50 | spring-cloud-starter-gateway 51 | true 52 | 53 | 54 | org.springframework.cloud 55 | spring-cloud-starter-netflix-zuul 56 | true 57 | 58 | 59 | org.owasp.antisamy 60 | antisamy 61 | 62 | 63 | org.owasp.encoder 64 | encoder-esapi 65 | 66 | 67 | org.owasp.esapi 68 | esapi 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-starter-security 73 | true 74 | 75 | 76 | org.springframework.security 77 | spring-security-cas 78 | true 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/AbstractBaseApiWrapper.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | import org.apache.dubbo.common.utils.ClassUtils; 11 | import org.springframework.beans.factory.InitializingBean; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.util.MultiValueMap; 14 | import org.springframework.util.PathMatcher; 15 | import org.springframework.util.StringUtils; 16 | 17 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFormat; 18 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 19 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties.XssConfig; 20 | import com.atommiddleware.cloud.core.context.DubboApiContext; 21 | import com.atommiddleware.cloud.core.security.XssSecurity; 22 | import com.atommiddleware.cloud.core.security.XssSecurity.XssFilterStrategy; 23 | import com.atommiddleware.cloud.core.serialize.Serialization; 24 | @SuppressWarnings("unchecked") 25 | public abstract class AbstractBaseApiWrapper implements BaseApiWrapper, InitializingBean { 26 | 27 | protected Set patterns = new HashSet(); 28 | 29 | @Autowired 30 | private Serialization serialization; 31 | @Autowired 32 | protected PathMatcher pathMatcher; 33 | @Autowired 34 | private DubboReferenceConfigProperties dubboReferenceConfigProperties; 35 | @Autowired(required = false) 36 | private XssSecurity xssSecurity; 37 | private boolean xssFilterEnable = true; 38 | // 0 response 1 request 2 all 39 | private XssFilterStrategy xssFilterStrategy; 40 | 41 | @Override 42 | public Set getPathPatterns() { 43 | return patterns; 44 | } 45 | 46 | protected void convertAttriToParam(ParamInfo paramInfo, Object obj, Object[] params) { 47 | if (paramInfo.isRequired() && null == obj) { 48 | throw new IllegalArgumentException("attribute Parameter verification exception"); 49 | } 50 | params[paramInfo.getIndex()] = obj; 51 | } 52 | 53 | protected void convertBodyToParam(ParamInfo paramInfo, Object body, Object[] params) 54 | throws IllegalAccessException, InvocationTargetException, InstantiationException { 55 | if (paramInfo.isRequired() && StringUtils.isEmpty(body)) { 56 | throw new IllegalArgumentException("body Parameter verification exception"); 57 | } 58 | final Map> mapClasses = DubboApiContext.MAP_CLASSES; 59 | Object param = null; 60 | if (null != body) { 61 | Class paramTypeClass = mapClasses.get(paramInfo.getParamType()); 62 | if (paramInfo.isSimpleType()) { 63 | String bodyString = null; 64 | if (body instanceof String) { 65 | bodyString = (String) body; 66 | } else { 67 | if (body instanceof MultiValueMap) { 68 | MultiValueMap multiValueMap = (MultiValueMap) body; 69 | bodyString = multiValueMap.getFirst(paramInfo.getParamName()); 70 | multiValueMap.clear(); 71 | } else { 72 | Map mapValue = (Map) body; 73 | String[] strValues = mapValue.get(paramInfo.getParamName()); 74 | if (null != strValues && strValues.length > 0) { 75 | bodyString = strValues[0]; 76 | } 77 | mapValue.clear(); 78 | } 79 | } 80 | if (!StringUtils.isEmpty(bodyString)) { 81 | if (checkRequestXssStrategy(paramTypeClass)) { 82 | bodyString = xssSecurity.xssClean(bodyString); 83 | } 84 | param = ClassUtils.convertPrimitive(paramTypeClass, bodyString); 85 | } 86 | } else { 87 | if (body instanceof String) { 88 | param = serialization.deserialize((String) body, paramTypeClass); 89 | } else { 90 | if (body instanceof MultiValueMap) { 91 | MultiValueMap multiValueMap = (MultiValueMap) body; 92 | param = serialization.convertValue(multiValueMap.toSingleValueMap(), paramTypeClass); 93 | multiValueMap.clear(); 94 | } else { 95 | Map multiValueMap = (Map) body; 96 | Map mapValues = new HashMap(); 97 | multiValueMap.forEach((key, v) -> { 98 | if (null != v && v.length > 0) { 99 | mapValues.put(key, v[0]); 100 | } 101 | }); 102 | param = serialization.convertValue(mapValues, paramTypeClass); 103 | mapValues.clear(); 104 | } 105 | } 106 | } 107 | } 108 | if (paramInfo.isRequired() && null == param) { 109 | throw new IllegalArgumentException( 110 | "paramName:[" + paramInfo.getParamName() + "] Parameter verification exception"); 111 | } 112 | params[paramInfo.getIndex()] = param; 113 | } 114 | 115 | private boolean checkRequestXssStrategy(Class paramTypeClass) { 116 | return paramTypeClass == String.class && xssFilterEnable && xssFilterStrategy == XssFilterStrategy.REQUEST; 117 | } 118 | 119 | protected void convertParam(List listParams, Map mapPathParams, Object[] params) { 120 | String paramValue = null; 121 | Object param = null; 122 | final Map> mapClasses = DubboApiContext.MAP_CLASSES; 123 | Class paramTypeClass; 124 | for (ParamInfo paramInfo : listParams) { 125 | param = null; 126 | paramTypeClass = mapClasses.get(paramInfo.getParamType()); 127 | if (ClassUtils.isSimpleType(paramTypeClass)) { 128 | paramValue = mapPathParams.get(paramInfo.getParamName()); 129 | if (!StringUtils.isEmpty(paramValue)) { 130 | if (checkRequestXssStrategy(paramTypeClass)) { 131 | paramValue = xssSecurity.xssClean(paramValue); 132 | } 133 | param = ClassUtils.convertPrimitive(paramTypeClass, paramValue); 134 | } 135 | } else { 136 | if (paramInfo.getParamFormat() == ParamFormat.MAP) { 137 | param = serialization.convertValue(mapPathParams, paramTypeClass); 138 | } else { 139 | paramValue = mapPathParams.get(paramInfo.getParamName()); 140 | param = serialization.deserialize(paramValue, paramTypeClass); 141 | } 142 | } 143 | if (paramInfo.isRequired() && null == param) { 144 | throw new IllegalArgumentException( 145 | "paramName:[" + paramInfo.getParamName() + "] Parameter verification exception"); 146 | } 147 | params[paramInfo.getIndex()] = param; 148 | } 149 | mapPathParams.clear(); 150 | } 151 | 152 | @Override 153 | public void afterPropertiesSet() throws Exception { 154 | XssConfig xssConfig=dubboReferenceConfigProperties.getSecurity().getXss(); 155 | xssFilterEnable = xssConfig.isEnable(); 156 | xssFilterStrategy = XssFilterStrategy.values()[xssConfig.getFilterStrategy()]; 157 | 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/AbstractDubboApiServletWrapper.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.util.Arrays; 6 | import java.util.Enumeration; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.TreeMap; 10 | import java.util.concurrent.CompletableFuture; 11 | import java.util.concurrent.ExecutionException; 12 | 13 | import javax.servlet.http.Cookie; 14 | import javax.servlet.http.HttpServletRequest; 15 | 16 | import org.springframework.util.CollectionUtils; 17 | import org.springframework.util.StringUtils; 18 | 19 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 20 | import com.atommiddleware.cloud.core.context.DubboApiContext; 21 | import com.atommiddleware.cloud.core.utils.HttpUtils; 22 | 23 | import lombok.extern.slf4j.Slf4j; 24 | @Slf4j 25 | public abstract class AbstractDubboApiServletWrapper extends AbstractBaseApiWrapper implements DubboApiServletWrapper{ 26 | 27 | @Override 28 | public CompletableFuture handler(String pathPattern, HttpServletRequest httpServletRequest, Object body) { 29 | throw new UnsupportedOperationException(); 30 | } 31 | 32 | private String decodeUrlEncode(String value) { 33 | if (!StringUtils.isEmpty(value)) { 34 | try { 35 | value=java.net.URLDecoder.decode(value, DubboApiContext.CHARSET); 36 | } catch (UnsupportedEncodingException e) { 37 | log.error("decode fail", e); 38 | } 39 | } 40 | return value; 41 | } 42 | protected void handlerConvertParams(String pathPattern, HttpServletRequest httpServletRequest, Object[] params, Object body) throws InterruptedException, ExecutionException, IllegalAccessException, InvocationTargetException, InstantiationException { 43 | final Map> mapGroupByParamType = DubboApiContext.MAP_PARAM_INFO.get(pathPattern); 44 | final Map mapPathParams = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); 45 | // cookie 46 | List listParams = mapGroupByParamType.get(ParamFromType.FROM_COOKIE); 47 | if (!CollectionUtils.isEmpty(listParams)) { 48 | Cookie[] cookies = httpServletRequest.getCookies(); 49 | Arrays.stream(cookies).forEach(o -> { 50 | mapPathParams.put(o.getName(), decodeUrlEncode(o.getValue())); 51 | }); 52 | convertParam(listParams, mapPathParams, params); 53 | } 54 | // body 55 | listParams = mapGroupByParamType.get(ParamFromType.FROM_BODY); 56 | if (!CollectionUtils.isEmpty(listParams)) { 57 | if (listParams.size() > 1) { 58 | throw new IllegalArgumentException("body Parameter verification exception"); 59 | } 60 | convertBodyToParam(listParams.get(0), body, params); 61 | } 62 | // header 63 | listParams = mapGroupByParamType.get(ParamFromType.FROM_HEADER); 64 | if (!CollectionUtils.isEmpty(listParams)) { 65 | Enumeration enumHeaderNames = httpServletRequest.getHeaderNames(); 66 | String headerValue=null; 67 | String headerName=null; 68 | while (enumHeaderNames.hasMoreElements()){ 69 | headerName=enumHeaderNames.nextElement(); 70 | headerValue = httpServletRequest.getHeader(headerName); 71 | if (!StringUtils.isEmpty(headerValue)) { 72 | mapPathParams.put(headerName,decodeUrlEncode(headerValue)); 73 | } 74 | } 75 | convertParam(listParams, mapPathParams, params); 76 | } 77 | 78 | // path 79 | listParams = mapGroupByParamType.get(ParamFromType.FROM_PATH); 80 | if (!CollectionUtils.isEmpty(listParams)) { 81 | pathMatcher.extractUriTemplateVariables(pathPattern, httpServletRequest.getRequestURI()).forEach((key,value)->{ 82 | mapPathParams.put(key, decodeUrlEncode(value)); 83 | }); 84 | convertParam(listParams, mapPathParams, params); 85 | } 86 | // queryParams 87 | listParams = mapGroupByParamType.get(ParamFromType.FROM_QUERYPARAMS); 88 | if (!CollectionUtils.isEmpty(listParams)) { 89 | mapPathParams.putAll(HttpUtils.getUrlParams(httpServletRequest, DubboApiContext.CHARSET)); 90 | convertParam(listParams, mapPathParams, params); 91 | } 92 | // from attribute 93 | listParams = mapGroupByParamType.get(ParamFromType.FROM_ATTRIBUTE); 94 | if (!CollectionUtils.isEmpty(listParams)) { 95 | listParams.forEach(o -> { 96 | convertAttriToParam(o, httpServletRequest.getAttribute(o.getParamName()), params); 97 | }); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/AbstractDubboApiWrapper.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.TreeMap; 8 | import java.util.concurrent.CompletableFuture; 9 | import java.util.concurrent.ExecutionException; 10 | 11 | import org.springframework.http.server.reactive.ServerHttpRequest; 12 | import org.springframework.util.CollectionUtils; 13 | import org.springframework.util.StringUtils; 14 | import org.springframework.web.server.ServerWebExchange; 15 | 16 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 17 | import com.atommiddleware.cloud.core.context.DubboApiContext; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | 21 | @Slf4j 22 | public abstract class AbstractDubboApiWrapper extends AbstractBaseApiWrapper implements DubboApiWrapper { 23 | 24 | @Override 25 | public CompletableFuture handler(String pathPattern, ServerWebExchange exchange, Object body) { 26 | throw new UnsupportedOperationException(); 27 | } 28 | 29 | private String decodeUrlEncode(String value) { 30 | if (!StringUtils.isEmpty(value)) { 31 | try { 32 | value = java.net.URLDecoder.decode(value, DubboApiContext.CHARSET); 33 | } catch (UnsupportedEncodingException e) { 34 | log.error("decode fail", e); 35 | } 36 | } 37 | return value; 38 | } 39 | 40 | protected void handlerConvertParams(String pathPattern, ServerWebExchange exchange, Object[] params, Object body) 41 | throws InterruptedException, ExecutionException, IllegalAccessException, InvocationTargetException, 42 | InstantiationException { 43 | ServerHttpRequest serverHttpRequest = exchange.getRequest(); 44 | final Map> mapGroupByParamType = DubboApiContext.MAP_PARAM_INFO.get(pathPattern); 45 | final Map mapPathParams = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); 46 | // cookie 47 | List listParams = mapGroupByParamType.get(ParamFromType.FROM_COOKIE); 48 | if (!CollectionUtils.isEmpty(listParams)) { 49 | serverHttpRequest.getCookies().forEach((key, values) -> { 50 | if (values != null && !values.isEmpty()) { 51 | mapPathParams.put(key, decodeUrlEncode(values.get(0).getValue())); 52 | } 53 | }); 54 | convertParam(listParams, mapPathParams, params); 55 | } 56 | 57 | // body 58 | listParams = mapGroupByParamType.get(ParamFromType.FROM_BODY); 59 | if (!CollectionUtils.isEmpty(listParams)) { 60 | if (listParams.size() > 1) { 61 | throw new IllegalArgumentException("body Parameter verification exception"); 62 | } 63 | convertBodyToParam(listParams.get(0), body, params); 64 | } 65 | // header 66 | listParams = mapGroupByParamType.get(ParamFromType.FROM_HEADER); 67 | if (!CollectionUtils.isEmpty(listParams)) { 68 | serverHttpRequest.getHeaders().toSingleValueMap().forEach((key, value) -> { 69 | mapPathParams.put(key, decodeUrlEncode(value)); 70 | }); 71 | convertParam(listParams, mapPathParams, params); 72 | } 73 | // path 74 | listParams = mapGroupByParamType.get(ParamFromType.FROM_PATH); 75 | if (!CollectionUtils.isEmpty(listParams)) { 76 | pathMatcher.extractUriTemplateVariables(pathPattern, serverHttpRequest.getPath().value()) 77 | .forEach((key, value) -> { 78 | mapPathParams.put(key, decodeUrlEncode(value)); 79 | }); 80 | convertParam(listParams, mapPathParams, params); 81 | } 82 | 83 | // queryParams 84 | listParams = mapGroupByParamType.get(ParamFromType.FROM_QUERYPARAMS); 85 | if (!CollectionUtils.isEmpty(listParams)) { 86 | serverHttpRequest.getQueryParams().toSingleValueMap().forEach((key, value) -> { 87 | mapPathParams.put(key, decodeUrlEncode(value)); 88 | }); 89 | convertParam(listParams, mapPathParams, params); 90 | } 91 | // from attribute 92 | listParams = mapGroupByParamType.get(ParamFromType.FROM_ATTRIBUTE); 93 | if (!CollectionUtils.isEmpty(listParams)) { 94 | listParams.forEach(o -> { 95 | convertAttriToParam(o, exchange.getAttribute(o.getParamName()), params); 96 | }); 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/AbstractDubboApiWrapperFactory.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.Method; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.springframework.boot.WebApplicationType; 10 | import org.springframework.core.DefaultParameterNameDiscoverer; 11 | import org.springframework.util.StringUtils; 12 | 13 | import com.atommiddleware.cloud.core.config.DubboReferenceConfig; 14 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 15 | import com.atommiddleware.cloud.core.config.ReferenceMethodConfig; 16 | import com.atommiddleware.cloud.core.config.ReferenceMethodConfig.ReferenceArgument; 17 | 18 | import javassist.CannotCompileException; 19 | import javassist.NotFoundException; 20 | import javassist.bytecode.ConstPool; 21 | import javassist.bytecode.annotation.Annotation; 22 | import javassist.bytecode.annotation.AnnotationMemberValue; 23 | import javassist.bytecode.annotation.ArrayMemberValue; 24 | import javassist.bytecode.annotation.BooleanMemberValue; 25 | import javassist.bytecode.annotation.IntegerMemberValue; 26 | import javassist.bytecode.annotation.StringMemberValue; 27 | 28 | public abstract class AbstractDubboApiWrapperFactory implements DubboApiWrapperFactory{ 29 | 30 | @Override 31 | public Class make(String id, Class interfaceClass, 32 | DubboReferenceConfigProperties dubboReferenceConfigProperties, WebApplicationType webApplicationType) 33 | throws CannotCompileException, NotFoundException, IllegalArgumentException, IllegalAccessException, 34 | IOException { 35 | throw new UnsupportedOperationException(); 36 | } 37 | 38 | protected String[] getMethodParamName(Method method) { 39 | method.setAccessible(true); 40 | DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer(); 41 | return discoverer.getParameterNames(method); 42 | } 43 | 44 | protected void handlerAnnotaionParams(DubboReferenceConfig dubboReferenceConfig, 45 | Annotation dubboReferenceAnnotation, ConstPool constPool) 46 | throws IllegalArgumentException, IllegalAccessException { 47 | Field[] fields = dubboReferenceConfig.getClass().getDeclaredFields(); 48 | boolean accessFlag = false; 49 | Object fieldValue = null; 50 | for (Field field : fields) { 51 | accessFlag = field.isAccessible(); 52 | if (!field.isAccessible()) 53 | field.setAccessible(true); 54 | fieldValue = field.get(dubboReferenceConfig); 55 | if (null != fieldValue) { 56 | handlerCommon(field.getName(), fieldValue, dubboReferenceAnnotation, constPool); 57 | if (fieldValue instanceof ReferenceMethodConfig[]) { 58 | ReferenceMethodConfig[] arrayReferenceMethodConfig = (ReferenceMethodConfig[]) fieldValue; 59 | if (arrayReferenceMethodConfig.length > 0) { 60 | List annotations = new ArrayList(); 61 | for (ReferenceMethodConfig referenceMethodConfig : arrayReferenceMethodConfig) { 62 | annotations.add(createDubboMethodAnnotation(referenceMethodConfig, constPool)); 63 | } 64 | AnnotationMemberValue[] annotationMemberValues = new AnnotationMemberValue[annotations.size()]; 65 | int i = 0; 66 | for (Annotation annotationTemp : annotations) { 67 | annotationMemberValues[i] = new AnnotationMemberValue(annotationTemp, constPool); 68 | i++; 69 | } 70 | ArrayMemberValue arrayMemberValue = new ArrayMemberValue(constPool); 71 | arrayMemberValue.setValue(annotationMemberValues); 72 | dubboReferenceAnnotation.addMemberValue("methods", arrayMemberValue); 73 | } 74 | } 75 | } 76 | 77 | field.setAccessible(accessFlag); 78 | } 79 | } 80 | 81 | protected void handlerCommon(String fieldName, Object fieldValue, Annotation annotation, ConstPool constPool) { 82 | if (fieldValue instanceof String) { 83 | String fieldValueStr = String.valueOf(fieldValue); 84 | if (!StringUtils.isEmpty(fieldValueStr)) { 85 | annotation.addMemberValue(fieldName, new StringMemberValue(fieldValueStr, constPool)); 86 | } 87 | } 88 | if (fieldValue instanceof Integer) { 89 | int fieldValueInteger = ((Integer) fieldValue).intValue(); 90 | if (fieldValueInteger > 0) { 91 | annotation.addMemberValue(fieldName, new IntegerMemberValue(constPool, (Integer) fieldValueInteger)); 92 | } 93 | } 94 | if (fieldValue instanceof Boolean) { 95 | boolean filedValueBoolean = (Boolean) fieldValue; 96 | annotation.addMemberValue(fieldName, new BooleanMemberValue(filedValueBoolean, constPool)); 97 | } 98 | if (fieldValue instanceof String[]) { 99 | String[] filedValueArray = (String[]) fieldValue; 100 | if (filedValueArray.length > 0) { 101 | StringMemberValue[] stringMemberValues = new StringMemberValue[filedValueArray.length]; 102 | int i = 0; 103 | for (String fieldValueStr : filedValueArray) { 104 | stringMemberValues[i] = new StringMemberValue(fieldValueStr, constPool); 105 | i++; 106 | } 107 | ArrayMemberValue arrayMemberValue = new ArrayMemberValue(constPool); 108 | arrayMemberValue.setValue(stringMemberValues); 109 | annotation.addMemberValue(fieldName, arrayMemberValue); 110 | } 111 | } 112 | } 113 | 114 | protected Annotation createDubboMethodAnnotation(ReferenceMethodConfig referenceMethodConfig, 115 | ConstPool constPool) throws IllegalArgumentException, IllegalAccessException { 116 | Annotation annotation = new Annotation(org.apache.dubbo.config.annotation.Method.class.getCanonicalName(), 117 | constPool); 118 | Field[] fields = referenceMethodConfig.getClass().getDeclaredFields(); 119 | boolean accessFlag = false; 120 | Object fieldValue = null; 121 | for (Field field : fields) { 122 | accessFlag = field.isAccessible(); 123 | if (!field.isAccessible()) 124 | field.setAccessible(true); 125 | fieldValue = field.get(referenceMethodConfig); 126 | if (null != fieldValue) { 127 | handlerCommon(field.getName(), fieldValue, annotation, constPool); 128 | if (fieldValue instanceof ReferenceArgument[]) { 129 | ReferenceArgument[] arrayReferenceArgument = (ReferenceArgument[]) fieldValue; 130 | if (arrayReferenceArgument.length > 0) { 131 | List annotations = new ArrayList(); 132 | for (ReferenceArgument referenceArgument : arrayReferenceArgument) { 133 | annotations.add(createDubboArgumentAnnotation(referenceArgument, constPool)); 134 | } 135 | AnnotationMemberValue[] annotationMemberValues = new AnnotationMemberValue[annotations.size()]; 136 | int i = 0; 137 | for (Annotation annotationTemp : annotations) { 138 | annotationMemberValues[i] = new AnnotationMemberValue(annotationTemp, constPool); 139 | i++; 140 | } 141 | ArrayMemberValue arrayMemberValue = new ArrayMemberValue(constPool); 142 | arrayMemberValue.setValue(annotationMemberValues); 143 | annotation.addMemberValue("arguments", arrayMemberValue); 144 | } 145 | } 146 | } 147 | 148 | field.setAccessible(accessFlag); 149 | } 150 | return annotation; 151 | } 152 | 153 | protected Annotation createDubboArgumentAnnotation(ReferenceArgument referenceArgument, ConstPool constPool) 154 | throws IllegalArgumentException, IllegalAccessException { 155 | Annotation annotation = new Annotation(org.apache.dubbo.config.annotation.Argument.class.getCanonicalName(), 156 | constPool); 157 | Field[] fields = referenceArgument.getClass().getDeclaredFields(); 158 | boolean accessFlag = false; 159 | Object fieldValue = null; 160 | for (Field field : fields) { 161 | accessFlag = field.isAccessible(); 162 | if (!field.isAccessible()) 163 | field.setAccessible(true); 164 | fieldValue = field.get(referenceArgument); 165 | if (null != fieldValue) { 166 | handlerCommon(field.getName(), fieldValue, annotation, constPool); 167 | } 168 | field.setAccessible(accessFlag); 169 | } 170 | return annotation; 171 | } 172 | 173 | 174 | } 175 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/BaseApiWrapper.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.util.Set; 4 | 5 | public interface BaseApiWrapper { 6 | 7 | Set getPathPatterns(); 8 | } 9 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DefaultResponseResult.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import org.springframework.core.io.buffer.DataBuffer; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.http.MediaType; 6 | import org.springframework.http.server.reactive.ServerHttpResponse; 7 | import org.springframework.web.server.ServerWebExchange; 8 | 9 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 10 | 11 | import reactor.core.publisher.Flux; 12 | import reactor.core.publisher.Mono; 13 | 14 | public class DefaultResponseResult implements ResponseReactiveResult { 15 | 16 | public DefaultResponseResult(DubboReferenceConfigProperties dubboReferenceConfigProperties) { 17 | 18 | } 19 | 20 | @Override 21 | public Mono reactiveFluxResponse(ServerWebExchange exchange, ServerHttpResponse response, 22 | Flux strDataBuffer) { 23 | response.getHeaders().setContentType(MediaType.APPLICATION_JSON); 24 | response.setStatusCode(HttpStatus.OK); 25 | return response.writeWith(strDataBuffer); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DefaultResponseServletResult.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintWriter; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | import org.springframework.http.HttpStatus; 12 | import org.springframework.http.MediaType; 13 | import org.springframework.util.StringUtils; 14 | 15 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 16 | import com.atommiddleware.cloud.core.serialize.Serialization; 17 | 18 | import lombok.extern.slf4j.Slf4j; 19 | 20 | @Slf4j 21 | public class DefaultResponseServletResult implements ResponseServletResult { 22 | 23 | private final DubboReferenceConfigProperties dubboReferenceConfigProperties; 24 | private final Serialization serialization; 25 | 26 | public DefaultResponseServletResult(DubboReferenceConfigProperties dubboReferenceConfigProperties, 27 | Serialization serialization) { 28 | this.dubboReferenceConfigProperties = dubboReferenceConfigProperties; 29 | this.serialization = serialization; 30 | } 31 | 32 | @Override 33 | public void sevletResponse(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, 34 | String result) { 35 | httpServletResponse.setCharacterEncoding(dubboReferenceConfigProperties.getCharset()); 36 | httpServletResponse.setStatus(HttpServletResponse.SC_OK); 37 | httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE); 38 | try { 39 | PrintWriter writer = httpServletResponse.getWriter(); 40 | if (StringUtils.isEmpty(result)) { 41 | result = ""; 42 | } 43 | writer.write(result); 44 | } catch (IOException e) { 45 | log.error("outData error", e); 46 | } 47 | } 48 | 49 | @Override 50 | public void sevletResponseException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, 51 | HttpStatus httpStatus, String msg) { 52 | httpServletResponse.setCharacterEncoding(dubboReferenceConfigProperties.getCharset()); 53 | httpServletResponse.setStatus(httpStatus.value()); 54 | httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE); 55 | Map map = new HashMap<>(); 56 | map.put("code", httpStatus.value()); 57 | map.put("msg", StringUtils.isEmpty(msg) ? httpStatus.getReasonPhrase() : msg); 58 | try { 59 | PrintWriter writer = httpServletResponse.getWriter(); 60 | writer.write(serialization.serialize(map)); 61 | } catch (IOException e) { 62 | log.error("outData error", e); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DefaultResponseZuulServletResult.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import javax.servlet.http.HttpServletResponse; 7 | 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.util.StringUtils; 11 | 12 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 13 | import com.atommiddleware.cloud.core.serialize.Serialization; 14 | import com.netflix.zuul.context.RequestContext; 15 | 16 | public class DefaultResponseZuulServletResult implements ResponseZuulServletResult { 17 | 18 | private final DubboReferenceConfigProperties dubboReferenceConfigProperties; 19 | private final Serialization serialization; 20 | 21 | public DefaultResponseZuulServletResult(DubboReferenceConfigProperties dubboReferenceConfigProperties, 22 | Serialization serialization) { 23 | this.dubboReferenceConfigProperties = dubboReferenceConfigProperties; 24 | this.serialization = serialization; 25 | } 26 | 27 | @Override 28 | public Object sevletZuulResponse(String result) { 29 | RequestContext ctx = RequestContext.getCurrentContext(); 30 | ctx.setResponseBody(StringUtils.isEmpty(result)?"":result); 31 | HttpServletResponse httpServletResponse = ctx.getResponse(); 32 | httpServletResponse.setCharacterEncoding(dubboReferenceConfigProperties.getCharset()); 33 | httpServletResponse.setStatus(HttpServletResponse.SC_OK); 34 | httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE); 35 | return null; 36 | } 37 | 38 | @Override 39 | public Object sevletZuulResponseException(HttpStatus httpStatus, String msg) { 40 | RequestContext ctx = RequestContext.getCurrentContext(); 41 | HttpServletResponse httpServletResponse = ctx.getResponse(); 42 | httpServletResponse.setCharacterEncoding(dubboReferenceConfigProperties.getCharset()); 43 | httpServletResponse.setStatus(httpStatus.value()); 44 | httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE); 45 | Map map = new HashMap<>(); 46 | map.put("code", httpStatus.value()); 47 | map.put("msg", StringUtils.isEmpty(msg) ? httpStatus.getReasonPhrase() : msg); 48 | ctx.setResponseBody(serialization.serialize(map)); 49 | return null; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DubboApiServletWrapper.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | public interface DubboApiServletWrapper extends BaseApiWrapper { 8 | 9 | CompletableFuture handler(String pathPattern, HttpServletRequest httpServletRequest, Object body); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DubboApiWrapper.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | 5 | import org.springframework.web.server.ServerWebExchange; 6 | 7 | public interface DubboApiWrapper extends BaseApiWrapper { 8 | 9 | CompletableFuture handler(String pathPattern, ServerWebExchange exchange, Object body); 10 | } 11 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DubboApiWrapperFactory.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.io.IOException; 4 | 5 | import org.springframework.boot.WebApplicationType; 6 | 7 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 8 | 9 | import javassist.CannotCompileException; 10 | import javassist.NotFoundException; 11 | 12 | public interface DubboApiWrapperFactory { 13 | 14 | public Class make(String id, Class interfaceClass, 15 | DubboReferenceConfigProperties dubboReferenceConfigProperties, WebApplicationType webApplicationType) 16 | throws CannotCompileException, NotFoundException, IllegalArgumentException, IllegalAccessException, 17 | IOException; 18 | } 19 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DubboGateWayApplicationListener.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; 5 | import org.springframework.context.ApplicationListener; 6 | import org.springframework.core.Ordered; 7 | 8 | public class DubboGateWayApplicationListener implements ApplicationListener,Ordered{ 9 | 10 | public static volatile WebApplicationType WEBAPPLICATIONTYPE; 11 | @Override 12 | public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { 13 | if(null==WEBAPPLICATIONTYPE) { 14 | WEBAPPLICATIONTYPE=event.getSpringApplication().getWebApplicationType(); 15 | } 16 | } 17 | 18 | @Override 19 | public int getOrder() { 20 | return HIGHEST_PRECEDENCE; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DubboGatewayImportBeanDefinitionRegistrar.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.io.IOException; 4 | import java.util.HashSet; 5 | import java.util.LinkedHashSet; 6 | import java.util.Map; 7 | import java.util.Set; 8 | 9 | import org.springframework.beans.BeansException; 10 | import org.springframework.beans.factory.BeanFactory; 11 | import org.springframework.beans.factory.BeanFactoryAware; 12 | import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; 13 | import org.springframework.beans.factory.config.BeanDefinition; 14 | import org.springframework.beans.factory.support.BeanDefinitionBuilder; 15 | import org.springframework.beans.factory.support.BeanDefinitionRegistry; 16 | import org.springframework.context.EnvironmentAware; 17 | import org.springframework.context.ResourceLoaderAware; 18 | import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; 19 | import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; 20 | import org.springframework.core.Ordered; 21 | import org.springframework.core.env.Environment; 22 | import org.springframework.core.io.ResourceLoader; 23 | import org.springframework.core.io.support.SpringFactoriesLoader; 24 | import org.springframework.core.type.AnnotationMetadata; 25 | import org.springframework.core.type.filter.AnnotationTypeFilter; 26 | import org.springframework.util.ClassUtils; 27 | import org.springframework.util.StringUtils; 28 | 29 | import com.atommiddleware.cloud.api.annotation.GateWayDubbo; 30 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 31 | import com.atommiddleware.cloud.core.context.DubboApiContext; 32 | 33 | import javassist.CannotCompileException; 34 | import javassist.NotFoundException; 35 | import lombok.extern.slf4j.Slf4j; 36 | 37 | @Slf4j 38 | public class DubboGatewayImportBeanDefinitionRegistrar 39 | implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware, BeanFactoryAware, Ordered { 40 | 41 | private ResourceLoader resourceLoader; 42 | 43 | private Environment environment; 44 | 45 | private DubboReferenceConfigProperties dubboReferenceConfigProperties; 46 | 47 | private BeanFactory beanFactory; 48 | 49 | @Override 50 | public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 51 | dubboReferenceConfigProperties = beanFactory.getBean(DubboReferenceConfigProperties.class); 52 | try { 53 | registerWrapper(importingClassMetadata, registry); 54 | } catch (IllegalArgumentException | IllegalAccessException | ClassNotFoundException | CannotCompileException 55 | | NotFoundException | IOException e) { 56 | log.error("registerwrapper fail", e); 57 | } 58 | registerDubboGatewayPostProcessor(registry); 59 | } 60 | 61 | private void registerDubboGatewayPostProcessor(BeanDefinitionRegistry registry) { 62 | registry.registerBeanDefinition(DubboGatewayPostProcessor.class.getName(), 63 | BeanDefinitionBuilder.genericBeanDefinition(DubboGatewayPostProcessor.class).getBeanDefinition()); 64 | } 65 | public ClassLoader getClassLoader() { 66 | if (this.resourceLoader != null) { 67 | return this.resourceLoader.getClassLoader(); 68 | } 69 | return ClassUtils.getDefaultClassLoader(); 70 | } 71 | public void registerWrapper(AnnotationMetadata metadata, BeanDefinitionRegistry registry) 72 | throws IllegalArgumentException, IllegalAccessException, ClassNotFoundException, CannotCompileException, 73 | NotFoundException, IOException { 74 | LinkedHashSet candidateComponents = new LinkedHashSet<>(); 75 | ClassPathScanningCandidateComponentProvider scanner = getScanner(); 76 | scanner.setResourceLoader(this.resourceLoader); 77 | scanner.addIncludeFilter(new AnnotationTypeFilter(GateWayDubbo.class)); 78 | Set basePackages = getBasePackages(metadata); 79 | for (String basePackage : basePackages) { 80 | candidateComponents.addAll(scanner.findCandidateComponents(basePackage)); 81 | } 82 | Class classWrapper = null; 83 | Map attributes; 84 | AnnotatedBeanDefinition beanDefinition; 85 | AnnotationMetadata annotationMetadata; 86 | for (BeanDefinition candidateComponent : candidateComponents) { 87 | if (candidateComponent instanceof AnnotatedBeanDefinition) { 88 | beanDefinition = (AnnotatedBeanDefinition) candidateComponent; 89 | annotationMetadata = beanDefinition.getMetadata(); 90 | attributes = annotationMetadata.getAnnotationAttributes(GateWayDubbo.class.getCanonicalName()); 91 | Object objId = attributes.get("id"); 92 | DubboApiWrapperFactory dubboApiWrapperFactory=SpringFactoriesLoader.loadFactories(DubboApiWrapperFactory.class, getClassLoader()).get(0); 93 | DubboApiContext.CHARSET=dubboReferenceConfigProperties.getCharset(); 94 | classWrapper = dubboApiWrapperFactory.make(null != objId ? String.valueOf(objId) : null, 95 | Class.forName(candidateComponent.getBeanClassName()), dubboReferenceConfigProperties,DubboGateWayApplicationListener.WEBAPPLICATIONTYPE); 96 | if (null != classWrapper) { 97 | registry.registerBeanDefinition(classWrapper.getSimpleName(), 98 | BeanDefinitionBuilder.genericBeanDefinition(classWrapper).getBeanDefinition()); 99 | } else { 100 | if (log.isWarnEnabled()) { 101 | log.warn("BeanClassName:[{}] has not method mapping", candidateComponent.getBeanClassName()); 102 | } 103 | } 104 | } 105 | } 106 | } 107 | 108 | protected ClassPathScanningCandidateComponentProvider getScanner() { 109 | return new ClassPathScanningCandidateComponentProvider(false, this.environment) { 110 | @Override 111 | protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { 112 | boolean isCandidate = false; 113 | if (beanDefinition.getMetadata().isIndependent()) { 114 | if (!beanDefinition.getMetadata().isAnnotation()) { 115 | isCandidate = true; 116 | } 117 | } 118 | return isCandidate; 119 | } 120 | }; 121 | } 122 | 123 | protected Set getBasePackages(AnnotationMetadata importingClassMetadata) { 124 | Map attributes = importingClassMetadata 125 | .getAnnotationAttributes(DubboGatewayScanner.class.getCanonicalName()); 126 | 127 | Set basePackages = new HashSet<>(); 128 | for (String pkg : (String[]) attributes.get("value")) { 129 | if (StringUtils.hasText(pkg)) { 130 | basePackages.add(pkg); 131 | } 132 | } 133 | for (String pkg : (String[]) attributes.get("basePackages")) { 134 | if (StringUtils.hasText(pkg)) { 135 | basePackages.add(pkg); 136 | } 137 | } 138 | for (Class clazz : (Class[]) attributes.get("basePackageClasses")) { 139 | basePackages.add(ClassUtils.getPackageName(clazz)); 140 | } 141 | 142 | if (basePackages.isEmpty()) { 143 | basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName())); 144 | } 145 | return basePackages; 146 | } 147 | 148 | @Override 149 | public void setEnvironment(Environment environment) { 150 | this.environment = environment; 151 | 152 | } 153 | 154 | @Override 155 | public void setResourceLoader(ResourceLoader resourceLoader) { 156 | this.resourceLoader = resourceLoader; 157 | } 158 | 159 | @Override 160 | public int getOrder() { 161 | return Ordered.LOWEST_PRECEDENCE; 162 | } 163 | 164 | @Override 165 | public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 166 | this.beanFactory = beanFactory; 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DubboGatewayPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.beans.BeansException; 6 | import org.springframework.beans.factory.SmartInitializingSingleton; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.context.ApplicationContextAware; 10 | import org.springframework.util.PathMatcher; 11 | 12 | import com.atommiddleware.cloud.core.context.DubboApiContext; 13 | 14 | public class DubboGatewayPostProcessor implements SmartInitializingSingleton, ApplicationContextAware { 15 | 16 | private ApplicationContext applicationContext; 17 | 18 | @Autowired 19 | private PathMatcher pathMatcher = null; 20 | 21 | @Override 22 | public void afterSingletonsInstantiated() { 23 | Map mapDubboApiWrapper = applicationContext.getBeansOfType(DubboApiWrapper.class); 24 | for (Map.Entry entry : mapDubboApiWrapper.entrySet()) { 25 | for (String pathPattern : entry.getValue().getPathPatterns()) { 26 | if (pathMatcher.isPattern(pathPattern)) { 27 | DubboApiContext.MAP_DUBBO_API_PATH_PATTERN_WRAPPER.put(pathPattern, entry.getValue()); 28 | } else { 29 | DubboApiContext.MAP_DUBBO_API_WRAPPER.put(pathPattern, entry.getValue()); 30 | } 31 | } 32 | } 33 | 34 | Map mapDubboApiServletWrapper = applicationContext 35 | .getBeansOfType(DubboApiServletWrapper.class); 36 | for (Map.Entry entry : mapDubboApiServletWrapper.entrySet()) { 37 | for (String pathPattern : entry.getValue().getPathPatterns()) { 38 | if (pathMatcher.isPattern(pathPattern)) { 39 | DubboApiContext.MAP_DUBBO_API_PATH_PATTERN_SERVLET_WRAPPER.put(pathPattern, entry.getValue()); 40 | } else { 41 | DubboApiContext.MAP_DUBBO_API_SERVLET_WRAPPER.put(pathPattern, entry.getValue()); 42 | } 43 | } 44 | } 45 | } 46 | 47 | @Override 48 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 49 | this.applicationContext = applicationContext; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/DubboGatewayScanner.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.context.annotation.Import; 10 | import org.springframework.core.annotation.AliasFor; 11 | 12 | @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE }) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Documented 15 | @Import(DubboGatewayImportBeanDefinitionRegistrar.class) 16 | public @interface DubboGatewayScanner { 17 | 18 | @AliasFor("basePackages") 19 | String[] value() default {}; 20 | 21 | @AliasFor("value") 22 | String[] basePackages() default {}; 23 | 24 | Class[] basePackageClasses() default {}; 25 | } 26 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/ParamInfo.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFormat; 4 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 5 | 6 | public class ParamInfo { 7 | 8 | public ParamInfo(int index,String paramName,ParamFromType paramFromType,String paramType,ParamFormat paramFormat, boolean simpleType,boolean childAllSimpleType,boolean required) { 9 | this.index=index; 10 | this.paramName=paramName; 11 | this.paramFromType=paramFromType; 12 | this.paramType=paramType; 13 | this.simpleType=simpleType; 14 | this.childAllSimpleType=simpleType; 15 | this.required=required; 16 | this.paramFormat=paramFormat; 17 | } 18 | 19 | private int index; 20 | 21 | private String paramName; 22 | 23 | private ParamFromType paramFromType; 24 | 25 | private String paramType; 26 | 27 | private boolean simpleType; 28 | 29 | private boolean childAllSimpleType; 30 | 31 | private boolean required; 32 | 33 | private ParamFormat paramFormat; 34 | 35 | public int getIndex() { 36 | return index; 37 | } 38 | 39 | public void setIndex(int index) { 40 | this.index = index; 41 | } 42 | 43 | public String getParamName() { 44 | return paramName; 45 | } 46 | 47 | public void setParamName(String paramName) { 48 | this.paramName = paramName; 49 | } 50 | 51 | public ParamFromType getParamFromType() { 52 | return paramFromType; 53 | } 54 | 55 | public void setParamFromType(ParamFromType paramFromType) { 56 | this.paramFromType = paramFromType; 57 | } 58 | 59 | public String getParamType() { 60 | return paramType; 61 | } 62 | 63 | public void setParamType(String paramType) { 64 | this.paramType = paramType; 65 | } 66 | 67 | public boolean isSimpleType() { 68 | return simpleType; 69 | } 70 | 71 | public void setSimpleType(boolean simpleType) { 72 | this.simpleType = simpleType; 73 | } 74 | 75 | public boolean isChildAllSimpleType() { 76 | return childAllSimpleType; 77 | } 78 | 79 | public void setChildAllSimpleType(boolean childAllSimpleType) { 80 | this.childAllSimpleType = childAllSimpleType; 81 | } 82 | 83 | public boolean isRequired() { 84 | return required; 85 | } 86 | 87 | public void setRequired(boolean required) { 88 | this.required = required; 89 | } 90 | 91 | public ParamFormat getParamFormat() { 92 | return paramFormat; 93 | } 94 | 95 | public void setParamFormat(ParamFormat paramFormat) { 96 | this.paramFormat = paramFormat; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/ParamMeta.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import com.atommiddleware.cloud.api.annotation.ParamAttribute; 4 | 5 | public class ParamMeta { 6 | 7 | public ParamMeta(String paramName, String paramType, ParamAttribute paramAttribute, boolean simpleType, 8 | boolean childAllSimpleType) { 9 | this.paramName = paramName; 10 | this.paramAttribute = paramAttribute; 11 | this.paramType = paramType; 12 | this.simpleType = simpleType; 13 | this.childAllSimpleType = childAllSimpleType; 14 | } 15 | 16 | private String paramName; 17 | 18 | private ParamAttribute paramAttribute; 19 | 20 | private String paramType; 21 | private boolean simpleType; 22 | 23 | private boolean childAllSimpleType; 24 | 25 | public String getParamType() { 26 | return paramType; 27 | } 28 | 29 | public void setParamType(String paramType) { 30 | this.paramType = paramType; 31 | } 32 | 33 | public String getParamName() { 34 | return paramName; 35 | } 36 | 37 | public void setParamName(String paramName) { 38 | this.paramName = paramName; 39 | } 40 | 41 | public ParamAttribute getParamAttribute() { 42 | return paramAttribute; 43 | } 44 | 45 | public void setParamAttribute(ParamAttribute paramAttribute) { 46 | this.paramAttribute = paramAttribute; 47 | } 48 | 49 | public boolean isSimpleType() { 50 | return simpleType; 51 | } 52 | 53 | public void setSimpleType(boolean simpleType) { 54 | this.simpleType = simpleType; 55 | } 56 | 57 | public boolean isChildAllSimpleType() { 58 | return childAllSimpleType; 59 | } 60 | 61 | public void setChildAllSimpleType(boolean childAllSimpleType) { 62 | this.childAllSimpleType = childAllSimpleType; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/PathMappingMethodInfo.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import com.atommiddleware.cloud.api.annotation.PathMapping; 8 | 9 | public class PathMappingMethodInfo { 10 | 11 | public PathMappingMethodInfo(Method method,PathMapping pathMapping) { 12 | this.method=method; 13 | this.pathMapping=pathMapping; 14 | } 15 | 16 | private Method method; 17 | 18 | private PathMapping pathMapping; 19 | 20 | private List listParamMeta=new ArrayList(); 21 | 22 | public List getListParamMeta() { 23 | return listParamMeta; 24 | } 25 | 26 | public Method getMethod() { 27 | return method; 28 | } 29 | 30 | public void setMethod(Method method) { 31 | this.method = method; 32 | } 33 | 34 | public PathMapping getPathMapping() { 35 | return pathMapping; 36 | } 37 | 38 | public void setPathMapping(PathMapping pathMapping) { 39 | this.pathMapping = pathMapping; 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/ResponseReactiveResult.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import org.springframework.core.io.buffer.DataBuffer; 4 | import org.springframework.http.server.reactive.ServerHttpResponse; 5 | import org.springframework.web.server.ServerWebExchange; 6 | 7 | import reactor.core.publisher.Flux; 8 | import reactor.core.publisher.Mono; 9 | 10 | public interface ResponseReactiveResult { 11 | public Mono reactiveFluxResponse(ServerWebExchange exchange,ServerHttpResponse response, Flux strDataBuffer); 12 | } 13 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/ResponseServletResult.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.http.HttpStatus; 7 | 8 | public interface ResponseServletResult { 9 | 10 | public void sevletResponse(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String result); 11 | 12 | public void sevletResponseException(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,HttpStatus httpStatus,String msg); 13 | } 14 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/annotation/ResponseZuulServletResult.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.annotation; 2 | 3 | import org.springframework.http.HttpStatus; 4 | 5 | public interface ResponseZuulServletResult { 6 | public Object sevletZuulResponse(String result); 7 | 8 | public Object sevletZuulResponseException(HttpStatus httpStatus,String msg); 9 | } 10 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/cas/CasAjaxAuthenticationEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.cas; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintWriter; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | import org.jasig.cas.client.util.CommonUtils; 12 | import org.springframework.beans.factory.InitializingBean; 13 | import org.springframework.http.HttpStatus; 14 | import org.springframework.http.MediaType; 15 | import org.springframework.security.cas.ServiceProperties; 16 | import org.springframework.security.core.AuthenticationException; 17 | import org.springframework.security.web.AuthenticationEntryPoint; 18 | import org.springframework.util.Assert; 19 | 20 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 21 | import com.atommiddleware.cloud.core.serialize.Serialization; 22 | import com.atommiddleware.cloud.core.utils.HttpUtils; 23 | 24 | import lombok.extern.slf4j.Slf4j; 25 | 26 | @Slf4j 27 | public class CasAjaxAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean { 28 | 29 | private final DubboReferenceConfigProperties dubboReferenceConfigProperties; 30 | private final Serialization serialization; 31 | 32 | public CasAjaxAuthenticationEntryPoint(DubboReferenceConfigProperties dubboReferenceConfigProperties, 33 | Serialization serialization) { 34 | this.dubboReferenceConfigProperties = dubboReferenceConfigProperties; 35 | this.serialization = serialization; 36 | } 37 | 38 | // ~ Instance fields 39 | // ================================================================================================ 40 | private ServiceProperties serviceProperties; 41 | 42 | private String loginUrl; 43 | 44 | /** 45 | * Determines whether the Service URL should include the session id for the 46 | * specific user. As of CAS 3.0.5, the session id will automatically be 47 | * stripped. However, older versions of CAS (i.e. CAS 2), do not automatically 48 | * strip the session identifier (this is a bug on the part of the older server 49 | * implementations), so an option to disable the session encoding is provided 50 | * for backwards compatibility. 51 | * 52 | * By default, encoding is enabled. 53 | */ 54 | private boolean encodeServiceUrlWithSessionId = true; 55 | 56 | // ~ Methods 57 | // ======================================================================================================== 58 | 59 | public void afterPropertiesSet() { 60 | Assert.hasLength(this.loginUrl, "loginUrl must be specified"); 61 | Assert.notNull(this.serviceProperties, "serviceProperties must be specified"); 62 | Assert.notNull(this.serviceProperties.getService(), "serviceProperties.getService() cannot be null."); 63 | } 64 | 65 | public final void commence(final HttpServletRequest servletRequest, final HttpServletResponse response, 66 | final AuthenticationException authenticationException) throws IOException { 67 | 68 | final String urlEncodedService = createServiceUrl(servletRequest, response); 69 | final String redirectUrl = createRedirectUrl(urlEncodedService); 70 | 71 | preCommence(servletRequest, response); 72 | if (HttpUtils.isAjax(servletRequest)) { 73 | response.setCharacterEncoding(dubboReferenceConfigProperties.getCharset()); 74 | response.setStatus(HttpStatus.UNAUTHORIZED.value()); 75 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 76 | Map map = new HashMap<>(); 77 | map.put("code", 302); 78 | map.put("location", redirectUrl); 79 | try { 80 | PrintWriter writer = response.getWriter(); 81 | writer.write(serialization.serialize(map, true)); 82 | } catch (IOException e) { 83 | log.error("outData error", e); 84 | } 85 | } else { 86 | response.sendRedirect(redirectUrl); 87 | } 88 | } 89 | 90 | /** 91 | * Constructs a new Service Url. The default implementation relies on the CAS 92 | * client to do the bulk of the work. 93 | * 94 | * @param request the HttpServletRequest 95 | * @param response the HttpServlet Response 96 | * @return the constructed service url. CANNOT be NULL. 97 | */ 98 | protected String createServiceUrl(final HttpServletRequest request, final HttpServletResponse response) { 99 | return CommonUtils.constructServiceUrl(null, response, this.serviceProperties.getService(), null, 100 | this.serviceProperties.getArtifactParameter(), this.encodeServiceUrlWithSessionId); 101 | } 102 | 103 | /** 104 | * Constructs the Url for Redirection to the CAS server. Default implementation 105 | * relies on the CAS client to do the bulk of the work. 106 | * 107 | * @param serviceUrl the service url that should be included. 108 | * @return the redirect url. CANNOT be NULL. 109 | */ 110 | protected String createRedirectUrl(final String serviceUrl) { 111 | return CommonUtils.constructRedirectUrl(this.loginUrl, this.serviceProperties.getServiceParameter(), serviceUrl, 112 | this.serviceProperties.isSendRenew(), false); 113 | } 114 | 115 | /** 116 | * Template method for you to do your own pre-processing before the redirect 117 | * occurs. 118 | * 119 | * @param request the HttpServletRequest 120 | * @param response the HttpServletResponse 121 | */ 122 | protected void preCommence(final HttpServletRequest request, final HttpServletResponse response) { 123 | 124 | } 125 | 126 | /** 127 | * The enterprise-wide CAS login URL. Usually something like 128 | * https://www.mycompany.com/cas/login. 129 | * 130 | * @return the enterprise-wide CAS login URL 131 | */ 132 | public final String getLoginUrl() { 133 | return this.loginUrl; 134 | } 135 | 136 | public final ServiceProperties getServiceProperties() { 137 | return this.serviceProperties; 138 | } 139 | 140 | public final void setLoginUrl(final String loginUrl) { 141 | this.loginUrl = loginUrl; 142 | } 143 | 144 | public final void setServiceProperties(final ServiceProperties serviceProperties) { 145 | this.serviceProperties = serviceProperties; 146 | } 147 | 148 | /** 149 | * Sets whether to encode the service url with the session id or not. 150 | * 151 | * @param encodeServiceUrlWithSessionId whether to encode the service url with 152 | * the session id or not. 153 | */ 154 | public final void setEncodeServiceUrlWithSessionId(final boolean encodeServiceUrlWithSessionId) { 155 | this.encodeServiceUrlWithSessionId = encodeServiceUrlWithSessionId; 156 | } 157 | 158 | /** 159 | * Sets whether to encode the service url with the session id or not. 160 | * 161 | * @return whether to encode the service url with the session id or not. 162 | * 163 | */ 164 | protected boolean getEncodeServiceUrlWithSessionId() { 165 | return this.encodeServiceUrlWithSessionId; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/config/ReferenceMethodConfig.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.config; 2 | 3 | public class ReferenceMethodConfig { 4 | 5 | private String name; 6 | 7 | private int timeout = -1; 8 | 9 | private int retries = -1; 10 | 11 | private String loadbalance = ""; 12 | 13 | private boolean sent = true; 14 | 15 | private int actives = 0; 16 | 17 | private int executes = 0; 18 | 19 | private boolean deprecated = false; 20 | 21 | private boolean sticky = false; 22 | 23 | boolean isReturn = true; 24 | 25 | private String oninvoke = ""; 26 | 27 | private String onreturn = ""; 28 | 29 | private String onthrow = ""; 30 | 31 | private String cache = ""; 32 | 33 | private String validation = ""; 34 | 35 | private String merger = ""; 36 | 37 | private ReferenceArgument[] arguments = {}; 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | public int getTimeout() { 48 | return timeout; 49 | } 50 | 51 | public void setTimeout(int timeout) { 52 | this.timeout = timeout; 53 | } 54 | 55 | public int getRetries() { 56 | return retries; 57 | } 58 | 59 | public void setRetries(int retries) { 60 | this.retries = retries; 61 | } 62 | 63 | public String getLoadbalance() { 64 | return loadbalance; 65 | } 66 | 67 | public void setLoadbalance(String loadbalance) { 68 | this.loadbalance = loadbalance; 69 | } 70 | 71 | public boolean isSent() { 72 | return sent; 73 | } 74 | 75 | public void setSent(boolean sent) { 76 | this.sent = sent; 77 | } 78 | 79 | public int getActives() { 80 | return actives; 81 | } 82 | 83 | public void setActives(int actives) { 84 | this.actives = actives; 85 | } 86 | 87 | public int getExecutes() { 88 | return executes; 89 | } 90 | 91 | public void setExecutes(int executes) { 92 | this.executes = executes; 93 | } 94 | 95 | public boolean isDeprecated() { 96 | return deprecated; 97 | } 98 | 99 | public void setDeprecated(boolean deprecated) { 100 | this.deprecated = deprecated; 101 | } 102 | 103 | public boolean isSticky() { 104 | return sticky; 105 | } 106 | 107 | public void setSticky(boolean sticky) { 108 | this.sticky = sticky; 109 | } 110 | 111 | public boolean isReturn() { 112 | return isReturn; 113 | } 114 | 115 | public void setReturn(boolean isReturn) { 116 | this.isReturn = isReturn; 117 | } 118 | 119 | public String getOninvoke() { 120 | return oninvoke; 121 | } 122 | 123 | public void setOninvoke(String oninvoke) { 124 | this.oninvoke = oninvoke; 125 | } 126 | 127 | public String getOnreturn() { 128 | return onreturn; 129 | } 130 | 131 | public void setOnreturn(String onreturn) { 132 | this.onreturn = onreturn; 133 | } 134 | 135 | public String getOnthrow() { 136 | return onthrow; 137 | } 138 | 139 | public void setOnthrow(String onthrow) { 140 | this.onthrow = onthrow; 141 | } 142 | 143 | public String getCache() { 144 | return cache; 145 | } 146 | 147 | public void setCache(String cache) { 148 | this.cache = cache; 149 | } 150 | 151 | public String getValidation() { 152 | return validation; 153 | } 154 | 155 | public void setValidation(String validation) { 156 | this.validation = validation; 157 | } 158 | 159 | public String getMerger() { 160 | return merger; 161 | } 162 | 163 | public void setMerger(String merger) { 164 | this.merger = merger; 165 | } 166 | 167 | public ReferenceArgument[] getArguments() { 168 | return arguments; 169 | } 170 | 171 | public void setArguments(ReferenceArgument[] arguments) { 172 | this.arguments = arguments; 173 | } 174 | 175 | public class ReferenceArgument { 176 | // argument: index -1 represents not set 177 | private int index = -1; 178 | 179 | // argument type 180 | private String type = ""; 181 | 182 | // callback interface 183 | private boolean callback = false; 184 | 185 | public int getIndex() { 186 | return index; 187 | } 188 | 189 | public void setIndex(int index) { 190 | this.index = index; 191 | } 192 | 193 | public String getType() { 194 | return type; 195 | } 196 | 197 | public void setType(String type) { 198 | this.type = type; 199 | } 200 | 201 | public boolean isCallback() { 202 | return callback; 203 | } 204 | 205 | public void setCallback(boolean callback) { 206 | this.callback = callback; 207 | } 208 | 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/context/DubboApiContext.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.context; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFromType; 8 | import com.atommiddleware.cloud.api.annotation.PathMapping; 9 | import com.atommiddleware.cloud.api.annotation.PathMapping.RequestMethod; 10 | import com.atommiddleware.cloud.core.annotation.DubboApiServletWrapper; 11 | import com.atommiddleware.cloud.core.annotation.DubboApiWrapper; 12 | import com.atommiddleware.cloud.core.annotation.ParamInfo; 13 | 14 | public class DubboApiContext { 15 | 16 | public final static Map MAP_DUBBO_API_WRAPPER = new HashMap(); 17 | public final static Map MAP_DUBBO_API_PATH_PATTERN_WRAPPER = new HashMap(); 18 | public final static Map PATTERNS_REQUESTMETHOD = new HashMap(); 19 | 20 | public static Map>> MAP_PARAM_INFO = new HashMap>>(); 21 | public static Map> MAP_CLASSES = new HashMap>(); 22 | 23 | public static String CHARSET = "UTF-8"; 24 | 25 | public final static Map MAP_DUBBO_API_SERVLET_WRAPPER = new HashMap(); 26 | public final static Map MAP_DUBBO_API_PATH_PATTERN_SERVLET_WRAPPER = new HashMap(); 27 | } 28 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/controller/ForwardingServiceController.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.controller; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintWriter; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.http.HttpStatus; 13 | import org.springframework.http.MediaType; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestMethod; 16 | import org.springframework.web.bind.annotation.RequestParam; 17 | import org.springframework.web.bind.annotation.RestController; 18 | import org.springframework.web.server.ServerWebInputException; 19 | 20 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 21 | import com.atommiddleware.cloud.core.serialize.Serialization; 22 | import com.atommiddleware.cloud.core.utils.HttpUtils; 23 | 24 | import lombok.extern.slf4j.Slf4j; 25 | 26 | @Slf4j 27 | @RestController 28 | public class ForwardingServiceController { 29 | 30 | @Autowired 31 | private DubboReferenceConfigProperties dubboReferenceConfigProperties; 32 | @Autowired 33 | private Serialization serialization; 34 | 35 | @RequestMapping(value = "/cas/redirect", method = { RequestMethod.POST, RequestMethod.GET }) 36 | public void redirect(@RequestParam("service") String service, HttpServletRequest httpRequest, 37 | HttpServletResponse httpServletResponse) { 38 | if (HttpUtils.isAjax(httpRequest)) { 39 | httpServletResponse.setCharacterEncoding(dubboReferenceConfigProperties.getCharset()); 40 | httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); 41 | httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE); 42 | Map map = new HashMap<>(); 43 | map.put("code", 302); 44 | map.put("location", service); 45 | try { 46 | PrintWriter writer = httpServletResponse.getWriter(); 47 | writer.write(serialization.serialize(map, true)); 48 | } catch (IOException e) { 49 | log.error("outData error", e); 50 | } 51 | } else { 52 | try { 53 | httpServletResponse.sendRedirect(service); 54 | } catch (IOException e) { 55 | throw new ServerWebInputException("fail redirect service"); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/dubbo/filter/UserFilter.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.dubbo.filter; 2 | 3 | import java.util.Map; 4 | 5 | import org.apache.dubbo.common.constants.CommonConstants; 6 | import org.apache.dubbo.common.extension.Activate; 7 | import org.apache.dubbo.rpc.Filter; 8 | import org.apache.dubbo.rpc.Invocation; 9 | import org.apache.dubbo.rpc.Invoker; 10 | import org.apache.dubbo.rpc.Result; 11 | import org.apache.dubbo.rpc.RpcContext; 12 | import org.apache.dubbo.rpc.RpcException; 13 | import org.springframework.util.CollectionUtils; 14 | 15 | import com.atommiddleware.cloud.security.cas.PrincipalObtain; 16 | 17 | @Activate(group = CommonConstants.CONSUMER) 18 | public class UserFilter implements Filter { 19 | 20 | private PrincipalObtain principalObtain; 21 | 22 | @Override 23 | public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { 24 | try { 25 | if (null != principalObtain) { 26 | Map mapPrincipal = principalObtain.getPrincipal(); 27 | if (!CollectionUtils.isEmpty(mapPrincipal)) { 28 | RpcContext.getContext().setAttachments(mapPrincipal); 29 | } 30 | } 31 | return invoker.invoke(invocation); 32 | } finally { 33 | RpcContext.getContext().clearAttachments(); 34 | } 35 | } 36 | 37 | public void setPrincipalObtain(PrincipalObtain principalObtain) { 38 | this.principalObtain = principalObtain; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/exception/JsonExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.exception; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import javax.validation.ConstraintViolationException; 7 | 8 | import org.springframework.boot.autoconfigure.web.ErrorProperties; 9 | import org.springframework.boot.autoconfigure.web.ResourceProperties; 10 | import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; 11 | import org.springframework.boot.web.error.ErrorAttributeOptions; 12 | import org.springframework.boot.web.reactive.error.ErrorAttributes; 13 | import org.springframework.context.ApplicationContext; 14 | import org.springframework.http.HttpStatus; 15 | import org.springframework.util.CollectionUtils; 16 | import org.springframework.util.StringUtils; 17 | import org.springframework.web.reactive.function.server.RequestPredicates; 18 | import org.springframework.web.reactive.function.server.RouterFunction; 19 | import org.springframework.web.reactive.function.server.RouterFunctions; 20 | import org.springframework.web.reactive.function.server.ServerRequest; 21 | import org.springframework.web.reactive.function.server.ServerResponse; 22 | import org.springframework.web.server.ResponseStatusException; 23 | 24 | import com.atommiddleware.cloud.security.validation.ParamValidator; 25 | 26 | public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler { 27 | 28 | private final ParamValidator paramValidator; 29 | 30 | public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, 31 | ErrorProperties errorProperties, ApplicationContext applicationContext, ParamValidator paramValidator) { 32 | super(errorAttributes, resourceProperties, errorProperties, applicationContext); 33 | this.paramValidator = paramValidator; 34 | } 35 | 36 | @Override 37 | protected Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) { 38 | Map responseExceptionMap = handleResponseException(request); 39 | if (!CollectionUtils.isEmpty(responseExceptionMap)) { 40 | return responseExceptionMap; 41 | } 42 | Map errorAttributes = super.getErrorAttributes(request, includeStackTrace); 43 | return response(errorAttributes); 44 | } 45 | 46 | @Override 47 | protected Map getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { 48 | Map responseExceptionMap = handleResponseException(request); 49 | if (!CollectionUtils.isEmpty(responseExceptionMap)) { 50 | return responseExceptionMap; 51 | } 52 | Map errorAttributes = super.getErrorAttributes(request, options); 53 | return response(errorAttributes); 54 | } 55 | 56 | private Map handleResponseException(ServerRequest request) { 57 | Throwable error = super.getError(request); 58 | if (error instanceof ConstraintViolationException) { 59 | ConstraintViolationException constraintViolationException = (ConstraintViolationException) error; 60 | String errorResult = paramValidator 61 | .appendFailReason(constraintViolationException.getConstraintViolations()); 62 | Map errorAttributes = new HashMap(); 63 | errorAttributes.put("code", HttpStatus.BAD_REQUEST.value()); 64 | errorAttributes.put("msg", 65 | StringUtils.isEmpty(errorResult) ? HttpStatus.BAD_REQUEST.getReasonPhrase() : errorResult); 66 | return errorAttributes; 67 | } 68 | if (error instanceof ResponseStatusException) { 69 | ResponseStatusException responseStatusException = (ResponseStatusException) error; 70 | Map errorAttributes = new HashMap(); 71 | errorAttributes.put("code", responseStatusException.getStatus().value()); 72 | errorAttributes.put("msg", 73 | StringUtils.isEmpty(responseStatusException.getReason()) 74 | ? responseStatusException.getStatus().getReasonPhrase() 75 | : responseStatusException.getReason()); 76 | return errorAttributes; 77 | } else { 78 | return null; 79 | } 80 | } 81 | 82 | @Override 83 | protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) { 84 | return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); 85 | } 86 | 87 | @Override 88 | protected int getHttpStatus(Map errorAttributes) { 89 | int statusCode = (int) errorAttributes.get("code"); 90 | return statusCode; 91 | } 92 | 93 | private Map response(Map errorAttributes) { 94 | Map map = new HashMap<>(); 95 | map.put("code", errorAttributes.get("status")); 96 | map.put("msg", errorAttributes.get("error")); 97 | return map; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/filter/DubboGlobalFilter.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.filter; 2 | 3 | import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR; 4 | import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; 5 | import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR; 6 | 7 | import java.io.UnsupportedEncodingException; 8 | import java.net.URI; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | import org.apache.http.HttpStatus; 14 | import org.springframework.cloud.gateway.filter.GatewayFilterChain; 15 | import org.springframework.cloud.gateway.filter.GlobalFilter; 16 | import org.springframework.cloud.gateway.support.NotFoundException; 17 | import org.springframework.core.Ordered; 18 | import org.springframework.core.io.buffer.DataBuffer; 19 | import org.springframework.core.io.buffer.DataBufferUtils; 20 | import org.springframework.core.io.buffer.NettyDataBuffer; 21 | import org.springframework.http.MediaType; 22 | import org.springframework.http.codec.ServerCodecConfigurer; 23 | import org.springframework.http.server.reactive.ServerHttpResponse; 24 | import org.springframework.util.PathMatcher; 25 | import org.springframework.web.reactive.function.client.WebClientResponseException; 26 | import org.springframework.web.reactive.function.server.ServerRequest; 27 | import org.springframework.web.server.MethodNotAllowedException; 28 | import org.springframework.web.server.ServerWebExchange; 29 | import org.springframework.web.server.UnsupportedMediaTypeStatusException; 30 | 31 | import com.atommiddleware.cloud.api.annotation.PathMapping.RequestMethod; 32 | import com.atommiddleware.cloud.core.annotation.DubboApiWrapper; 33 | import com.atommiddleware.cloud.core.annotation.ResponseReactiveResult; 34 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 35 | import com.atommiddleware.cloud.core.context.DubboApiContext; 36 | import com.atommiddleware.cloud.core.serialize.Serialization; 37 | 38 | import lombok.extern.slf4j.Slf4j; 39 | import reactor.core.publisher.Flux; 40 | import reactor.core.publisher.Mono; 41 | @Slf4j 42 | public class DubboGlobalFilter implements GlobalFilter, Ordered{ 43 | 44 | private final PathMatcher pathMatcher; 45 | private final Serialization serialization; 46 | private final DubboReferenceConfigProperties dubboReferenceConfigProperties; 47 | private final ResponseReactiveResult responseResult; 48 | private ServerCodecConfigurer serverCodecConfigurer; 49 | private final List supportedTypes=new ArrayList(); 50 | public DubboGlobalFilter(PathMatcher pathMatcher, Serialization serialization, 51 | DubboReferenceConfigProperties dubboReferenceConfigProperties, ServerCodecConfigurer serverCodecConfigurer, 52 | ResponseReactiveResult responseResult) { 53 | this.pathMatcher = pathMatcher; 54 | this.serialization = serialization; 55 | this.dubboReferenceConfigProperties = dubboReferenceConfigProperties; 56 | this.serverCodecConfigurer = serverCodecConfigurer; 57 | this.responseResult = responseResult; 58 | supportedTypes.add(MediaType.APPLICATION_JSON); 59 | supportedTypes.add(MediaType.APPLICATION_JSON_UTF8); 60 | supportedTypes.add(MediaType.APPLICATION_FORM_URLENCODED); 61 | } 62 | 63 | @Override 64 | public int getOrder() { 65 | return 10151; 66 | } 67 | 68 | @Override 69 | public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { 70 | URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR); 71 | String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR); 72 | if (url == null 73 | || (!"dubbo".equals(url.getScheme()) && !"dubbo".equals(schemePrefix))) { 74 | return chain.filter(exchange); 75 | } 76 | String path = exchange.getRequest().getPath().value(); 77 | String pathPatternTemp = path; 78 | DubboApiWrapper dubboApiWrapperTemp = DubboApiContext.MAP_DUBBO_API_WRAPPER.get(path); 79 | if (null == dubboApiWrapperTemp) { 80 | for (Map.Entry entry : DubboApiContext.MAP_DUBBO_API_PATH_PATTERN_WRAPPER 81 | .entrySet()) { 82 | if (pathMatcher.match(entry.getKey(), path)) { 83 | dubboApiWrapperTemp = entry.getValue(); 84 | pathPatternTemp = entry.getKey(); 85 | break; 86 | } 87 | } 88 | } 89 | if (null == dubboApiWrapperTemp) { 90 | throw NotFoundException.create(true, "not find path "+path+" service"); 91 | } else { 92 | final String pathPattern = pathPatternTemp; 93 | RequestMethod requestMethod = DubboApiContext.PATTERNS_REQUESTMETHOD.get(pathPattern); 94 | ServerHttpResponse response = exchange.getResponse(); 95 | String httpMethodName = exchange.getRequest().getMethod().name(); 96 | if (!httpMethodName.equals(requestMethod.name())) { 97 | log.error("path:[{}] requestMethod is fail PathMapping requestMethod:[{}]", pathPattern, 98 | requestMethod.name()); 99 | throw new MethodNotAllowedException(requestMethod.name(),null); 100 | } else { 101 | final DubboApiWrapper dubboApiWrapper = dubboApiWrapperTemp; 102 | if (httpMethodName.equals(RequestMethod.POST.name())) { 103 | MediaType mediaType=exchange.getRequest().getHeaders().getContentType(); 104 | if(null==mediaType) { 105 | log.error("path:[{}] body param media must application/json or application/x-www-form-urlencoded", pathPattern); 106 | throw new UnsupportedMediaTypeStatusException(exchange.getRequest().getHeaders().getContentType(), 107 | supportedTypes); 108 | } 109 | if (mediaType.equals(MediaType.APPLICATION_JSON) 110 | || mediaType.equals(MediaType.APPLICATION_JSON_UTF8)) { 111 | Object attrBody = exchange.getAttribute(CACHED_REQUEST_BODY_ATTR); 112 | if (null != attrBody) { 113 | NettyDataBuffer nettyDataBuffer = (NettyDataBuffer) attrBody; 114 | return responseResult.reactiveFluxResponse(exchange, response, 115 | Flux.just(nettyDataBuffer).flatMap(o -> { 116 | byte[] bytes = new byte[o.readableByteCount()]; 117 | o.read(bytes); 118 | DataBufferUtils.release(o); 119 | String bodyString = null; 120 | try { 121 | bodyString = new String(bytes, dubboReferenceConfigProperties.getCharset()); 122 | } catch (UnsupportedEncodingException e) { 123 | log.error("fai", e); 124 | throw WebClientResponseException.create(HttpStatus.SC_INTERNAL_SERVER_ERROR, "byte to String fail", null, null, null); 125 | } 126 | return Mono 127 | .fromFuture(dubboApiWrapper.handler(pathPattern, exchange, bodyString)) 128 | .flatMap(k -> { 129 | return Mono.just(response.bufferFactory() 130 | .wrap(serialization.serializeByte(k))); 131 | }); 132 | })); 133 | } else { 134 | ServerRequest serverRequest = ServerRequest.create(exchange, 135 | serverCodecConfigurer.getReaders()); 136 | return responseResult.reactiveFluxResponse(exchange, response, 137 | Flux.just(serverRequest.bodyToMono(String.class).defaultIfEmpty("")).flatMap(u -> { 138 | return u.flatMap(o -> { 139 | return Mono 140 | .fromFuture( 141 | dubboApiWrapper.handler(pathPattern, exchange, o)) 142 | .flatMap(k -> { 143 | return Mono.just(response.bufferFactory() 144 | .wrap(serialization.serializeByte(k))); 145 | }); 146 | }); 147 | })); 148 | } 149 | } else if (mediaType.equals(MediaType.APPLICATION_FORM_URLENCODED)) { 150 | // form表单形式 151 | ServerRequest serverRequest = ServerRequest.create(exchange, 152 | serverCodecConfigurer.getReaders()); 153 | Flux fx = Flux.from(serverRequest.formData().flatMap(o -> { 154 | return Mono.fromFuture(dubboApiWrapper.handler(pathPattern, exchange, o)).flatMap(k -> { 155 | return Mono.just(response.bufferFactory().wrap(serialization.serializeByte(k))); 156 | }); 157 | })); 158 | return responseResult.reactiveFluxResponse(exchange, response, fx); 159 | } else { 160 | log.error("path:[{}] body param media must application/json or application/x-www-form-urlencoded", pathPattern); 161 | throw new UnsupportedMediaTypeStatusException(exchange.getRequest().getHeaders().getContentType(), 162 | supportedTypes); 163 | } 164 | } else if (httpMethodName.equals(RequestMethod.GET.name())) { 165 | Flux fx = Flux 166 | .from(Mono.fromFuture(dubboApiWrapper.handler(pathPattern, exchange, null)).flatMap(k -> { 167 | return Mono.just(response.bufferFactory().wrap(serialization.serializeByte(k))); 168 | })); 169 | 170 | return responseResult.reactiveFluxResponse(exchange, response, fx); 171 | } else { 172 | log.error("Only get and post are supported for the time being path:[{}] requestMethod:[{}]", 173 | pathPattern, requestMethod.name()); 174 | throw new MethodNotAllowedException(requestMethod.name(),null); 175 | } 176 | } 177 | } 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/filter/ServletErrorFilter.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.filter; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.Filter; 6 | import javax.servlet.FilterChain; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | import org.springframework.http.HttpStatus; 14 | import org.springframework.web.server.ResponseStatusException; 15 | 16 | import com.atommiddleware.cloud.core.annotation.ResponseServletResult; 17 | 18 | import lombok.extern.slf4j.Slf4j; 19 | 20 | @Slf4j 21 | public class ServletErrorFilter implements Filter { 22 | 23 | private final ResponseServletResult responseResult; 24 | 25 | public ServletErrorFilter(ResponseServletResult responseResult) { 26 | this.responseResult = responseResult; 27 | } 28 | 29 | @Override 30 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 31 | throws IOException, ServletException { 32 | try { 33 | chain.doFilter(request, response); 34 | } catch (ResponseStatusException e) { 35 | log.error(" fail to apply ", e); 36 | responseResult.sevletResponseException((HttpServletRequest) request, (HttpServletResponse) response, 37 | e.getStatus(), e.getReason()); 38 | return; 39 | } catch (Exception e) { 40 | log.error("fail to apply ", e); 41 | responseResult.sevletResponseException((HttpServletRequest) request, (HttpServletResponse) response, 42 | HttpStatus.INTERNAL_SERVER_ERROR, null); 43 | } 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/filter/ZuulErrorFilter.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.filter; 2 | 3 | import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.util.ReflectionUtils; 6 | 7 | import com.atommiddleware.cloud.core.annotation.ResponseZuulServletResult; 8 | import com.netflix.zuul.context.RequestContext; 9 | 10 | public class ZuulErrorFilter extends SendErrorFilter { 11 | 12 | private final ResponseZuulServletResult responseZuulServletResult; 13 | 14 | public ZuulErrorFilter(ResponseZuulServletResult responseZuulServletResult) { 15 | this.responseZuulServletResult = responseZuulServletResult; 16 | } 17 | 18 | @Override 19 | public int filterOrder() { 20 | return super.filterOrder() - 1; 21 | } 22 | 23 | @Override 24 | public Object run() { 25 | try { 26 | RequestContext ctx = RequestContext.getCurrentContext(); 27 | ExceptionHolder exception = findZuulException(ctx.getThrowable()); 28 | ctx.remove("throwable"); 29 | ctx.set("SEND_ERROR_FILTER_RAN", true); 30 | HttpStatus httpStatus = HttpStatus.valueOf(exception.getStatusCode()); 31 | if (null != httpStatus) { 32 | responseZuulServletResult.sevletZuulResponseException(httpStatus, null); 33 | } else { 34 | responseZuulServletResult.sevletZuulResponseException(HttpStatus.INTERNAL_SERVER_ERROR, null); 35 | } 36 | } catch (Exception ex) { 37 | ReflectionUtils.rethrowRuntimeException(ex); 38 | } 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/security/DefaultPrincipalObtain.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.security; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.security.core.context.SecurityContext; 10 | import org.springframework.security.core.context.SecurityContextHolder; 11 | import org.springframework.util.CollectionUtils; 12 | 13 | import com.atommiddleware.cloud.core.serialize.Serialization; 14 | import com.atommiddleware.cloud.security.cas.PrincipalObtain; 15 | @SuppressWarnings("unchecked") 16 | public class DefaultPrincipalObtain implements PrincipalObtain { 17 | 18 | @Autowired 19 | private Serialization serialization; 20 | 21 | public final List principalAttrs; 22 | 23 | public DefaultPrincipalObtain(Serialization serialization, List principalAttrs) { 24 | this.principalAttrs = principalAttrs; 25 | } 26 | 27 | @Override 28 | public Map getPrincipal() { 29 | SecurityContext securityContext = SecurityContextHolder.getContext(); 30 | if (null != securityContext) { 31 | Authentication authentication = securityContext.getAuthentication(); 32 | if (null != authentication && !CollectionUtils.isEmpty(principalAttrs)) { 33 | Map mapPrincipal = serialization.convertValue(authentication.getPrincipal(), Map.class, 34 | true); 35 | if (!CollectionUtils.isEmpty(mapPrincipal)) { 36 | Map mapResult = new HashMap(); 37 | Object attr = null; 38 | for (String principalAttrKey : principalAttrs) { 39 | attr = mapPrincipal.get(principalAttrKey); 40 | if (null!=attr) { 41 | mapResult.put(principalAttrKey, String.valueOf(attr)); 42 | } 43 | } 44 | return mapResult; 45 | } 46 | } 47 | } 48 | return null; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/security/DefaultXssSecurity.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.security; 2 | 3 | import org.owasp.validator.html.AntiSamy; 4 | import org.owasp.validator.html.CleanResults; 5 | import org.owasp.validator.html.Policy; 6 | import org.owasp.validator.html.PolicyException; 7 | import org.owasp.validator.html.ScanException; 8 | import org.springframework.beans.factory.InitializingBean; 9 | import org.springframework.core.io.Resource; 10 | import org.springframework.core.io.ResourceLoader; 11 | import org.springframework.core.io.support.ResourcePatternResolver; 12 | import org.springframework.core.io.support.ResourcePatternUtils; 13 | import org.springframework.util.StringUtils; 14 | 15 | import lombok.extern.slf4j.Slf4j; 16 | 17 | @Slf4j 18 | public class DefaultXssSecurity implements XssSecurity, InitializingBean { 19 | 20 | private final String DEFALUT_ANTISAMYFILEPATH = "classpath*:antisamy-ebay.xml"; 21 | private final ResourceLoader resourceLoader; 22 | private final String antisamyFileLocationPattern; 23 | private Policy policy = null; 24 | 25 | public DefaultXssSecurity(ResourceLoader resourceLoader, String antisamyFileLocationPattern) { 26 | this.resourceLoader = resourceLoader; 27 | this.antisamyFileLocationPattern = StringUtils.isEmpty(antisamyFileLocationPattern) ? DEFALUT_ANTISAMYFILEPATH 28 | : antisamyFileLocationPattern; 29 | } 30 | 31 | private String antisamyXssClean(String origionText) { 32 | AntiSamy antiSamy = new AntiSamy(); 33 | try { 34 | final CleanResults cr = antiSamy.scan(origionText, policy); 35 | return cr.getCleanHTML(); 36 | } catch (ScanException e) { 37 | log.error("clean html fail", e); 38 | } catch (PolicyException e) { 39 | log.error("clean html policy fail", e); 40 | } 41 | return origionText; 42 | } 43 | 44 | @Override 45 | public String xssClean(String origionText) { 46 | if (StringUtils.isEmpty(origionText)) { 47 | return origionText; 48 | } 49 | return antisamyXssClean(origionText); 50 | } 51 | 52 | @Override 53 | public void afterPropertiesSet() throws Exception { 54 | ResourcePatternResolver resourcePatternResolver = ResourcePatternUtils 55 | .getResourcePatternResolver(resourceLoader); 56 | Resource[] resources = resourcePatternResolver.getResources(antisamyFileLocationPattern); 57 | for (Resource resource : resources) { 58 | try { 59 | policy = Policy.getInstance(resource.getInputStream()); 60 | if (log.isInfoEnabled()) { 61 | log.info("load antisamyFile path:[{}]", resource.getURL()); 62 | } 63 | break; 64 | } catch (PolicyException e) { 65 | log.error("load policy fail", e); 66 | } 67 | } 68 | if (null == policy) { 69 | throw new IllegalArgumentException("not find antisamy xml"); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/security/EncodeHtmlXssSecurity.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.security; 2 | 3 | import org.owasp.encoder.Encode; 4 | import org.springframework.util.StringUtils; 5 | 6 | public class EncodeHtmlXssSecurity implements XssSecurity { 7 | 8 | private String htmlEncode(String origionText) { 9 | return Encode.forHtmlContent(origionText); 10 | } 11 | 12 | @Override 13 | public String xssClean(String origionText) { 14 | if(StringUtils.isEmpty(origionText)) { 15 | return origionText; 16 | } 17 | return htmlEncode(origionText); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/security/EsapiEncodeHtmlXssSecurity.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.security; 2 | 3 | import org.owasp.esapi.ESAPI; 4 | import org.springframework.util.StringUtils; 5 | 6 | public class EsapiEncodeHtmlXssSecurity implements XssSecurity { 7 | 8 | @Override 9 | public String xssClean(String origionText) { 10 | if (StringUtils.isEmpty(origionText)) { 11 | return origionText; 12 | } 13 | return ESAPI.encoder().encodeForHTML(origionText); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/security/XssSecurity.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.security; 2 | 3 | public interface XssSecurity { 4 | 5 | String xssClean(String origionText); 6 | 7 | public enum XssFilterStrategy { 8 | RESPONSE, REQUEST 9 | } 10 | 11 | public enum XssFilterMode { 12 | ESAPI, ANTISAMY, ESAPI_EASY; 13 | public String valueString() { 14 | return String.valueOf(this.ordinal()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/serialize/CustomXssObjectMapper.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.serialize; 2 | 3 | import java.io.IOException; 4 | 5 | import com.atommiddleware.cloud.core.security.XssSecurity; 6 | import com.fasterxml.jackson.core.JsonGenerator; 7 | import com.fasterxml.jackson.core.JsonParser; 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.core.Version; 10 | import com.fasterxml.jackson.databind.DeserializationContext; 11 | import com.fasterxml.jackson.databind.JsonDeserializer; 12 | import com.fasterxml.jackson.databind.JsonSerializer; 13 | import com.fasterxml.jackson.databind.ObjectMapper; 14 | import com.fasterxml.jackson.databind.SerializerProvider; 15 | import com.fasterxml.jackson.databind.module.SimpleModule; 16 | 17 | public class CustomXssObjectMapper extends ObjectMapper { 18 | 19 | /** 20 | * 21 | */ 22 | private static final long serialVersionUID = 1L; 23 | 24 | private final XssSecurity xssSecurity; 25 | 26 | public CustomXssObjectMapper(XssSecurity xssSecurity) { 27 | this.xssSecurity = xssSecurity; 28 | SimpleModule module = new SimpleModule("HTML XSS Serializer", 29 | new Version(1, 0, 0, "FINAL", "com.atommiddleware", "ep-jsonmodule")); 30 | module.addSerializer(new JsonHtmlXssSerializer(String.class)); 31 | module.addDeserializer(String.class, new JsonHtmlXssDeserializer(String.class)); 32 | this.registerModule(module); 33 | } 34 | 35 | class JsonHtmlXssSerializer extends JsonSerializer { 36 | 37 | public JsonHtmlXssSerializer(Class string) { 38 | super(); 39 | } 40 | 41 | public Class handledType() { 42 | return String.class; 43 | } 44 | 45 | @Override 46 | public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { 47 | String encodedValue = xssSecurity.xssClean(value); 48 | if (null != encodedValue) { 49 | gen.writeString(encodedValue); 50 | } 51 | } 52 | } 53 | 54 | class JsonHtmlXssDeserializer extends JsonDeserializer { 55 | 56 | public JsonHtmlXssDeserializer(Class string) { 57 | super(); 58 | } 59 | 60 | @Override 61 | public Class handledType() { 62 | return String.class; 63 | } 64 | 65 | @Override 66 | public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) 67 | throws IOException, JsonProcessingException { 68 | String value = jsonParser.getValueAsString(); 69 | if (value != null) { 70 | return xssSecurity.xssClean(value); 71 | } 72 | return value; 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/serialize/JacksonSerialization.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.serialize; 2 | 3 | import org.springframework.util.StringUtils; 4 | 5 | import com.atommiddleware.cloud.core.security.XssSecurity; 6 | import com.atommiddleware.cloud.core.security.XssSecurity.XssFilterStrategy; 7 | import com.fasterxml.jackson.annotation.JsonInclude; 8 | import com.fasterxml.jackson.core.JsonParser; 9 | import com.fasterxml.jackson.core.JsonProcessingException; 10 | import com.fasterxml.jackson.databind.DeserializationFeature; 11 | import com.fasterxml.jackson.databind.MapperFeature; 12 | import com.fasterxml.jackson.databind.ObjectMapper; 13 | import com.fasterxml.jackson.databind.SerializationFeature; 14 | 15 | import lombok.extern.slf4j.Slf4j; 16 | 17 | @Slf4j 18 | public class JacksonSerialization implements Serialization { 19 | 20 | private final ObjectMapper mapper; 21 | private final CustomXssObjectMapper customXssObjectMapper; 22 | private final boolean enableXssFilter; 23 | private final XssFilterStrategy xssFilterStrategy; 24 | 25 | public JacksonSerialization(boolean enableXssFilter, XssSecurity xssSecurity, XssFilterStrategy xssFilterStrategy) { 26 | this.enableXssFilter = enableXssFilter; 27 | this.xssFilterStrategy = xssFilterStrategy; 28 | customXssObjectMapper = new CustomXssObjectMapper(xssSecurity); 29 | initMapper(customXssObjectMapper); 30 | mapper = new ObjectMapper(); 31 | initMapper(mapper); 32 | // 对于空的对象转json的时候不抛出错误 33 | 34 | } 35 | 36 | private void initMapper(ObjectMapper mapperTemp) { 37 | mapperTemp.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); 38 | // 允许属性名称没有引号 39 | mapperTemp.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 40 | // 允许单引号 41 | mapperTemp.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); 42 | // 设置输入时忽略在json字符串中存在但在java对象实际没有的属性 43 | mapperTemp.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 44 | // 设置输出时包含属性的风格 45 | mapperTemp.setSerializationInclusion(JsonInclude.Include.NON_NULL); 46 | // 忽略大小写 47 | mapperTemp.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); 48 | } 49 | 50 | @Override 51 | public String serialize(Object value) { 52 | if (value == null) { 53 | return null; 54 | } 55 | try { 56 | if (enableXssFilter && xssFilterStrategy == XssFilterStrategy.RESPONSE) { 57 | // 响应要过滤xss 58 | return customXssObjectMapper.writeValueAsString(value); 59 | } else { 60 | return mapper.writeValueAsString(value); 61 | } 62 | } catch (JsonProcessingException e) { 63 | log.error(" toJsonString error", e); 64 | } 65 | return null; 66 | } 67 | 68 | @Override 69 | public byte[] serializeByte(Object value) { 70 | if (value == null) { 71 | return null; 72 | } 73 | try { 74 | if (enableXssFilter && xssFilterStrategy == XssFilterStrategy.RESPONSE) { 75 | // 响应要过滤xss 76 | return customXssObjectMapper.writeValueAsBytes(value); 77 | } else { 78 | return mapper.writeValueAsBytes(value); 79 | } 80 | } catch (JsonProcessingException e) { 81 | log.error(" toJsonByte error", e); 82 | } 83 | return null; 84 | } 85 | 86 | @Override 87 | public T deserialize(String input, Class clazz) { 88 | if(StringUtils.isEmpty(input)) { 89 | return null; 90 | } 91 | T t = null; 92 | try { 93 | if (enableXssFilter && xssFilterStrategy == XssFilterStrategy.REQUEST) { 94 | // 请求需要过滤xss 95 | t = customXssObjectMapper.readValue(input, clazz); 96 | } else { 97 | t = mapper.readValue(input, clazz); 98 | } 99 | } catch (Exception e) { 100 | log.error(" parse json to class [{}] ", clazz.getSimpleName()); 101 | } 102 | return t; 103 | } 104 | 105 | @Override 106 | public T convertValue(Object obj, Class clazz) { 107 | if(null==obj) { 108 | return null; 109 | } 110 | T t = null; 111 | try { 112 | if (enableXssFilter && xssFilterStrategy == XssFilterStrategy.REQUEST) { 113 | t = customXssObjectMapper.convertValue(obj, clazz); 114 | } else { 115 | t = mapper.convertValue(obj, clazz); 116 | } 117 | } catch (Exception e) { 118 | log.error(" parse json to class [{}] error", clazz.getSimpleName()); 119 | } 120 | return t; 121 | } 122 | 123 | @Override 124 | public String serialize(Object value, boolean ignoreXss) { 125 | if(null==value) { 126 | return null; 127 | } 128 | try { 129 | if (ignoreXss) { 130 | return mapper.writeValueAsString(value); 131 | } else { 132 | return customXssObjectMapper.writeValueAsString(value); 133 | } 134 | } catch (JsonProcessingException e) { 135 | log.error(" toJsonString error", e); 136 | } 137 | return null; 138 | } 139 | 140 | @Override 141 | public T deserialize(String input, Class clazz, boolean ignoreXss) { 142 | if(StringUtils.isEmpty(input)) { 143 | return null; 144 | } 145 | try { 146 | if (ignoreXss) { 147 | return mapper.readValue(input, clazz); 148 | } else { 149 | return customXssObjectMapper.readValue(input, clazz); 150 | } 151 | } catch (Exception e) { 152 | log.error(" toJsonString error", e); 153 | } 154 | return null; 155 | } 156 | 157 | @Override 158 | public T convertValue(Object obj, Class clazz, boolean ignoreXss) { 159 | if(null==obj) { 160 | return null; 161 | } 162 | T t = null; 163 | try { 164 | if (!ignoreXss) { 165 | t = customXssObjectMapper.convertValue(obj, clazz); 166 | } else { 167 | t = mapper.convertValue(obj, clazz); 168 | } 169 | } catch (Exception e) { 170 | log.error(" parse json to class [{}] error", clazz.getSimpleName()); 171 | } 172 | return t; 173 | } 174 | 175 | } 176 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/serialize/Serialization.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.serialize; 2 | 3 | import org.springframework.lang.NonNull; 4 | 5 | public interface Serialization { 6 | 7 | String serialize(Object object); 8 | 9 | byte[] serializeByte(Object object); 10 | 11 | T deserialize(@NonNull String input, Class clazz); 12 | 13 | T convertValue(Object obj,Class clazz); 14 | 15 | String serialize(Object object,boolean ignoreXss); 16 | 17 | T deserialize(@NonNull String input, Class clazz,boolean ignoreXss); 18 | 19 | T convertValue(Object obj,Class clazz,boolean ignoreXss); 20 | } 21 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/java/com/atommiddleware/cloud/core/utils/HttpUtils.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.core.utils; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.io.UnsupportedEncodingException; 8 | import java.net.URLDecoder; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | 14 | import org.springframework.util.StringUtils; 15 | 16 | public class HttpUtils { 17 | 18 | private static final String AJAX_HEADER_VALUE = "XMLHttpRequest"; 19 | private static final String AJAX_HEADER_NAME = "X-Requested-With"; 20 | private static final String IS_AJAX_REQUEST = "is_ajax_request"; 21 | 22 | /** 23 | * 将URL请求参数转换成Map 24 | * 25 | * @param request 26 | */ 27 | public static Map getUrlParams(HttpServletRequest request, String charset) { 28 | Map result = new HashMap<>(16); 29 | String param = ""; 30 | try { 31 | String urlPar = request.getQueryString(); 32 | if (!StringUtils.isEmpty(urlPar)) { 33 | param = URLDecoder.decode(urlPar, charset); 34 | } else { 35 | return result; 36 | } 37 | } catch (UnsupportedEncodingException e) { 38 | } 39 | String[] params = param.split("&"); 40 | for (String s : params) { 41 | int index = s.indexOf("="); 42 | result.put(s.substring(0, index), s.substring(index + 1)); 43 | } 44 | return result; 45 | } 46 | 47 | /** 48 | * 获取 Body 参数 49 | * 50 | * @param request 51 | */ 52 | public static String getBodyParam(final HttpServletRequest request) throws IOException { 53 | return inputConvertToString(request.getInputStream()); 54 | } 55 | 56 | public static InputStream getBodyInputStream(final HttpServletRequest request) throws IOException { 57 | return request.getInputStream(); 58 | } 59 | 60 | public static String inputConvertToString(InputStream input) throws IOException { 61 | BufferedReader reader = new BufferedReader(new InputStreamReader(input)); 62 | String str = ""; 63 | StringBuilder wholeStr = new StringBuilder(); 64 | // 一行一行的读取body体里面的内容; 65 | while ((str = reader.readLine()) != null) { 66 | wholeStr.append(str); 67 | } 68 | return wholeStr.toString(); 69 | } 70 | 71 | public static boolean isAjax(HttpServletRequest httpRequest) { 72 | final boolean xmlHttpRequest = AJAX_HEADER_VALUE.equalsIgnoreCase(httpRequest.getHeader(AJAX_HEADER_NAME)); 73 | final boolean hasDynamicAjaxParameter = Boolean.TRUE.toString() 74 | .equalsIgnoreCase(httpRequest.getHeader(IS_AJAX_REQUEST)); 75 | final boolean hasDynamicAjaxHeader = Boolean.TRUE.toString() 76 | .equalsIgnoreCase(httpRequest.getParameter(IS_AJAX_REQUEST)); 77 | return xmlHttpRequest || hasDynamicAjaxParameter || hasDynamicAjaxHeader; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter: -------------------------------------------------------------------------------- 1 | userFilter=com.atommiddleware.cloud.core.dubbo.filter.UserFilter -------------------------------------------------------------------------------- /dubbo-gateway-core/src/main/resources/esapi/validation.properties: -------------------------------------------------------------------------------- 1 | # The ESAPI validator does many security checks on input, such as canonicalization 2 | # and whitelist validation. Note that all of these validation rules are applied *after* 3 | # canonicalization. Double-encoded characters (even with different encodings involved, 4 | # are never allowed. 5 | # 6 | # To use: 7 | # 8 | # First set up a pattern below. You can choose any name you want, prefixed by the word 9 | # "Validation." For example: 10 | # Validation.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ 11 | # 12 | # Then you can validate in your code against the pattern like this: 13 | # ESAPI.validator().isValidInput("User Email", input, "Email", maxLength, allowNull); 14 | # Where maxLength and allowNull are set for you needs, respectively. 15 | # 16 | # But note, when you use boolean variants of validation functions, you lose critical 17 | # canonicalization. It is preferable to use the "get" methods (which throw exceptions) and 18 | # and use the returned user input which is in canonical form. Consider the following: 19 | # 20 | # try { 21 | # someObject.setEmail(ESAPI.validator().getValidInput("User Email", input, "Email", maxLength, allowNull)); 22 | # 23 | Validator.SafeString=^[.\\p{Alnum}\\p{Space}]{0,1024}$ 24 | Validator.Email=^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ 25 | Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ 26 | Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&;%\\$#_]*)?$ 27 | Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$ 28 | Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$ 29 | 30 | -------------------------------------------------------------------------------- /dubbo-gateway-parent/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | org.sonatype.oss 8 | oss-parent 9 | 7 10 | 11 | 12 | 13 | The Apache Software License, Version 2.0 14 | http://www.apache.org/licenses/LICENSE-2.0.txt 15 | repo 16 | 17 | 18 | 19 | master 20 | git@github.com:smallbeanteng/dubbo-gateway.git 21 | scm:git:git@github.com:smallbeanteng/dubbo-gateway.git 22 | scm:git:git@github.com:smallbeanteng/dubbo-gateway.git 23 | 24 | 25 | 26 | smallbeanteng 27 | smallbeanteng@163.com 28 | smallbeanteng 29 | 30 | 31 | 32 | Github Issue 33 | https://github.com/smallbeanteng/dubbo-gateway/issues 34 | 35 | 36 | 37 | ossrh 38 | https://s01.oss.sonatype.org/content/repositories/snapshots 39 | 40 | 41 | ossrh 42 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 43 | 44 | 45 | 46 | com.atommiddleware 47 | dubbo-gateway-parent 48 | ${revision} 49 | ${project.artifactId} 50 | pom 51 | The dubbo-gateway parent module of dubbo-gateway 52 | https://github.com/smallbeanteng/dubbo-gateway 53 | 54 | 1.1.4.6-GA 55 | 1.2.5 56 | 1.8 57 | 1.8 58 | UTF-8 59 | UTF-8 60 | 2.3.12.RELEASE 61 | 2.2.7.RELEASE 62 | Hoxton.SR12 63 | 5.2.16.RELEASE 64 | 1.6.5 65 | 1.2.3 66 | 2.2.0.0 67 | 68 | 69 | 70 | 71 | 72 | org.springframework 73 | spring-web 74 | ${spring-web.version} 75 | 76 | 77 | org.springframework.boot 78 | spring-boot-dependencies 79 | ${spring-boot.version} 80 | pom 81 | import 82 | 83 | 84 | com.alibaba.cloud 85 | spring-cloud-alibaba-dependencies 86 | ${spring-cloud-alibaba.version} 87 | pom 88 | import 89 | 90 | 91 | org.springframework.cloud 92 | spring-cloud-dependencies 93 | ${spring-cloud.version} 94 | pom 95 | import 96 | 97 | 98 | org.owasp.antisamy 99 | antisamy 100 | ${antisamy.version} 101 | 102 | 103 | org.owasp.encoder 104 | encoder-esapi 105 | ${encoder-esapi.version} 106 | 107 | 108 | org.owasp.esapi 109 | esapi 110 | ${esapi.version} 111 | 112 | 113 | 114 | 115 | 116 | 117 | org.apache.maven.plugins 118 | maven-source-plugin 119 | 2.2.1 120 | 121 | 122 | attach-sources 123 | 124 | jar-no-fork 125 | 126 | 127 | 128 | 129 | 130 | org.apache.maven.plugins 131 | maven-site-plugin 132 | 3.7.1 133 | 134 | 135 | org.apache.maven.plugins 136 | maven-javadoc-plugin 137 | 2.9.1 138 | 139 | 140 | attach-javadocs 141 | 142 | jar 143 | 144 | 145 | 146 | 147 | 148 | org.apache.maven.plugins 149 | maven-release-plugin 150 | 151 | true 152 | false 153 | release 154 | deploy 155 | ${arguments} 156 | 157 | 158 | 159 | org.codehaus.mojo 160 | flatten-maven-plugin 161 | ${maven_flatten_version} 162 | 163 | true 164 | resolveCiFriendliesOnly 165 | 166 | 167 | 168 | flatten 169 | process-resources 170 | 171 | flatten 172 | 173 | 174 | 175 | flatten.clean 176 | clean 177 | 178 | clean 179 | 180 | 181 | 182 | 183 | 184 | org.apache.maven.plugins 185 | maven-gpg-plugin 186 | 1.5 187 | 188 | 189 | sign-artifacts 190 | verify 191 | 192 | sign 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | ../dubbo-gateway-api 201 | ../dubbo-gateway-core 202 | ../dubbo-gateway-spring-boot-autoconfigure 203 | ../dubbo-gateway-spring-boot-starter 204 | ../dubbo-gateway-security 205 | 206 | 207 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-api/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | com.atommiddleware 8 | dubbo-gateway-parent 9 | ${revision} 10 | ../dubbo-gateway-parent/pom.xml 11 | 12 | jar 13 | dubbo-gateway-sample-api 14 | ${project.artifactId} 15 | The sample api of dubbo gateway 16 | 17 | 18 | 19 | org.hibernate.validator 20 | hibernate-validator 21 | 22 | 23 | com.atommiddleware 24 | dubbo-gateway-api 25 | ${project.parent.version} 26 | 27 | 28 | org.hibernate.validator 29 | hibernate-validator 30 | 31 | 32 | org.springframework 33 | spring-context 34 | true 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-api/src/main/java/com/atommiddleware/cloud/sample/api/Result.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.api; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Result extends HashMap { 6 | 7 | public Result() { 8 | this.setCode(0); 9 | } 10 | 11 | public Result(int code) { 12 | this(code, null); 13 | } 14 | 15 | public Result(int code, String msg) { 16 | this.setCode(code); 17 | this.put("msg", msg); 18 | } 19 | 20 | public Result setData(String key, Object value) { 21 | this.put(key, value); 22 | return this; 23 | } 24 | 25 | public Integer getCode() { 26 | return (Integer) this.get("code"); 27 | } 28 | 29 | public void setCode(Integer code) { 30 | this.put("code", code); 31 | } 32 | 33 | public String getMsg() { 34 | return (String) this.get("msg"); 35 | } 36 | 37 | public void setMsg(String msg) { 38 | this.put("msg", msg); 39 | } 40 | 41 | public static Result from() { 42 | return new Result(); 43 | } 44 | 45 | public static Result fromCode(int code) { 46 | return new Result(code); 47 | } 48 | 49 | public static Result fromCodeAndMsg(int code, String msg) { 50 | return new Result(code, msg); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-api/src/main/java/com/atommiddleware/cloud/sample/api/order/OrderQuery.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.api.order; 2 | 3 | import com.atommiddleware.cloud.api.annotation.FromQueryParams; 4 | import com.atommiddleware.cloud.api.annotation.GateWayDubbo; 5 | import com.atommiddleware.cloud.api.annotation.PathMapping; 6 | import com.atommiddleware.cloud.api.annotation.PathMapping.RequestMethod; 7 | import com.atommiddleware.cloud.sample.api.Result; 8 | 9 | @GateWayDubbo("orderQuery") 10 | public interface OrderQuery { 11 | @PathMapping(value = "/order/getOrder",requestMethod = RequestMethod.GET) 12 | Result getOrder(@FromQueryParams("orderCode") String orderCode); 13 | } 14 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-api/src/main/java/com/atommiddleware/cloud/sample/api/order/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.api.order; 2 | 3 | import com.atommiddleware.cloud.api.annotation.FromBody; 4 | import com.atommiddleware.cloud.api.annotation.GateWayDubbo; 5 | import com.atommiddleware.cloud.api.annotation.PathMapping; 6 | import com.atommiddleware.cloud.sample.api.Result; 7 | 8 | @GateWayDubbo("orderService") 9 | public interface OrderService { 10 | @PathMapping(path = "/order/placeOrder") 11 | Result placeOrder(@FromBody String orderCode); 12 | } 13 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-api/src/main/java/com/atommiddleware/cloud/sample/api/order/domain/Order.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.api.order.domain; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Order implements Serializable { 6 | 7 | private static final long serialVersionUID = 1L; 8 | private String orderCode; 9 | 10 | public String getOrderCode() { 11 | return orderCode; 12 | } 13 | 14 | public void setOrderCode(String orderCode) { 15 | this.orderCode = orderCode; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-api/src/main/java/com/atommiddleware/cloud/sample/api/user/UserService.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.api.user; 2 | 3 | import com.atommiddleware.cloud.api.annotation.FromBody; 4 | import com.atommiddleware.cloud.api.annotation.FromCookie; 5 | import com.atommiddleware.cloud.api.annotation.FromHeader; 6 | import com.atommiddleware.cloud.api.annotation.FromPath; 7 | import com.atommiddleware.cloud.api.annotation.FromQueryParams; 8 | import com.atommiddleware.cloud.api.annotation.GateWayDubbo; 9 | import com.atommiddleware.cloud.api.annotation.ParamAttribute.ParamFormat; 10 | import com.atommiddleware.cloud.api.annotation.PathMapping; 11 | import com.atommiddleware.cloud.api.annotation.PathMapping.RequestMethod; 12 | import com.atommiddleware.cloud.sample.api.Result; 13 | import com.atommiddleware.cloud.sample.api.user.domain.User; 14 | 15 | @GateWayDubbo("userService") 16 | public interface UserService { 17 | 18 | /** 19 | * hello world 20 | * @return hello 21 | */ 22 | @PathMapping(value="/sample/helloWorld",requestMethod=RequestMethod.GET) 23 | Result helloWorld(); 24 | /** 25 | * 参数为空post请求 26 | * @return 结果 27 | */ 28 | @PathMapping(value="/sample/helloWorldPost",requestMethod=RequestMethod.POST) 29 | Result helloWorldPost(); 30 | /** 31 | * 返回值为空 32 | */ 33 | @PathMapping(value="/sample/helloVoid",requestMethod=RequestMethod.GET) 34 | void helloVoid(); 35 | /** 36 | * 返回值为空 post请求 37 | */ 38 | @PathMapping(value="/sample/helloVoidPost",requestMethod=RequestMethod.POST) 39 | void helloVoidPost(); 40 | /** 41 | * 注册用户 42 | * @param user 用户信息 43 | * @return 注册结果 44 | */ 45 | @PathMapping("/sample/registerUser") 46 | Result registerUser(@FromBody User user); 47 | /** 48 | * 对象数据源来自header,headerName=user,headerValue=json(UrlEncoder后的字符串) 49 | * @param user 用户信息 50 | * @return 结果 51 | */ 52 | @PathMapping(value="/sample/registerUserFromHeader",requestMethod=RequestMethod.GET) 53 | Result registerUserFromHeader(@FromHeader(value = "user",paramFormat = ParamFormat.JSON) User user); 54 | /** 55 | * header中以key value方式传递对象参数,headerName=headerValue转换为beanPropertyName=beanPropertyValue 56 | * headerName 对应bean 的propertyName,headerValue对应bean的propertyValue 57 | * @param user 用戶信息 58 | * @return 结果 59 | */ 60 | @PathMapping(value="/sample/registerUserFromHeaderMap",requestMethod=RequestMethod.GET) 61 | Result registerUserFromHeaderMap(@FromHeader(value="user",paramFormat =ParamFormat.MAP) User user); 62 | /** 63 | * 对象数据源来自cookie,cookieName=user,cookieValue=json(UrlEncoder后的字符串) 64 | * @param user 用户信息 65 | * @return 结果 66 | */ 67 | @PathMapping(value="/sample/registerUserFromCookie",requestMethod=RequestMethod.GET) 68 | Result registerUserFromCookie(@FromCookie(value="user",paramFormat = ParamFormat.JSON) User user); 69 | /** 70 | * cookie中以 key value 方式传递对象参数,cookieName=cookieValue转化为beanPropertyName=beanPropertyValue 71 | * cookieName 对应bean 的propertyName,cookieValue对应bean的propertyValue,不支持嵌套对象转换,嵌套对象或复杂参数请用json 72 | * @param user 用戶信息 73 | * @return 结果 74 | */ 75 | @PathMapping(value="/sample/registerUserFromCookieMap",requestMethod=RequestMethod.GET) 76 | Result registerUserFromCookieMap(@FromCookie(value="user",paramFormat = ParamFormat.MAP) User user); 77 | /** 78 | * 对象数据源来自path,{user}=json(UrlEncoder后的字符串) 79 | * @param user 用户信息 80 | * @return 结果 81 | */ 82 | @PathMapping(value="/sample/registerUserFromPath/{user}",requestMethod=RequestMethod.GET) 83 | Result registerUserFromPath(@FromPath(value="user",paramFormat = ParamFormat.JSON) User user); 84 | /** 85 | * path pattern对应bean的属性名称 86 | * @param user 用户信息 87 | * @return 结果 88 | */ 89 | @PathMapping(value="/sample/registerUserFromPathMap/{userName}/{age}/{gender}",requestMethod=RequestMethod.GET) 90 | Result registerUserFromPathMap(@FromPath(value="user",paramFormat = ParamFormat.MAP) User user); 91 | 92 | /** 93 | * 对象参数来源于query json字符串,user=json(UrlEncoder后的字符串) 94 | * @param user 用户信息 95 | * @return 结果 96 | */ 97 | @PathMapping(value="/sample/getUserInfoFromQueryParamsParamFormatJSON",requestMethod=RequestMethod.GET) 98 | Result getUserInfoFromQueryParamsParamFormatJSON(@FromQueryParams(value="user",paramFormat = ParamFormat.JSON)User user); 99 | 100 | /** 101 | * 对象参数来源于query,以key,value方式传参,key对应bean propertyName,value对应propertyValue,嵌套对象或复杂对象请使用JSON 102 | * @param user 用户 103 | * @return 结果 104 | */ 105 | @PathMapping(value="/sample/getUserInfoFromQueryParamsParamFormatMap",requestMethod=RequestMethod.GET) 106 | Result getUserInfoFromQueryParamsParamFormatMap(@FromQueryParams(value="user",paramFormat = ParamFormat.MAP)User user); 107 | /** 108 | * 数据来源queryParam 109 | * @param userId 用户id 110 | * @return 取消注销结果 111 | */ 112 | @PathMapping(value="/sample/unRegisterUser",requestMethod=RequestMethod.GET) 113 | Result unRegisterUser(@FromQueryParams("userId")Long userId); 114 | /** 115 | * 数据来源path 116 | * @param userId 用戶id 117 | * @return 结果 118 | */ 119 | @PathMapping(value="/sample/getUserInfo/{userId}/{gender}",requestMethod=RequestMethod.GET) 120 | Result getUserInfo(@FromPath("userId") Long userId,@FromPath("gender") Short gender); 121 | /** 122 | * 数据来源header 和cookie 123 | * @param userId 用户id 124 | * @param age 年龄 125 | * @return 返回查询结果 126 | */ 127 | @PathMapping(value="/sample/getUserInfo/byHeaderAndCookie",requestMethod=RequestMethod.GET) 128 | Result getUserInfo(@FromHeader("userId")Long userId,@FromCookie("age") Integer age); 129 | 130 | /** 131 | * 全场景 132 | * @param userId 用户id 133 | * @param age 年龄 134 | * @param gender 性别 135 | * @param user 用户信息 136 | * @return 查询结果 137 | */ 138 | @PathMapping("/sample/getUserUserInfoAll/{userId}") 139 | Result getUserUserInfoAll(@FromPath("userId") Long userId,@FromCookie("age")Integer age,@FromHeader("gender")Long gender,@FromBody User user); 140 | } 141 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-api/src/main/java/com/atommiddleware/cloud/sample/api/user/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.api.user.domain; 2 | 3 | import java.io.Serializable; 4 | import java.util.Arrays; 5 | import java.util.Date; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | 9 | import org.hibernate.validator.constraints.Length; 10 | 11 | public class User implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | @NotBlank(message = "用户名称不能为空") 16 | @Length(min = 1, max = 200, message = "用户名称请输入1-200个英文字符或者1-100个汉字") 17 | private String userName; 18 | 19 | private String password; 20 | 21 | private Integer age; 22 | 23 | private Short gender; 24 | 25 | private Date dt; 26 | 27 | private WorkHistory workHistory = new WorkHistory(); 28 | 29 | public String getUserName() { 30 | return userName; 31 | } 32 | 33 | public void setUserName(String userName) { 34 | this.userName = userName; 35 | } 36 | 37 | public String getPassword() { 38 | return password; 39 | } 40 | 41 | public void setPassword(String password) { 42 | this.password = password; 43 | } 44 | 45 | public Integer getAge() { 46 | return age; 47 | } 48 | 49 | public void setAge(Integer age) { 50 | this.age = age; 51 | } 52 | 53 | public Short getGender() { 54 | return gender; 55 | } 56 | 57 | public void setGender(Short gender) { 58 | this.gender = gender; 59 | } 60 | 61 | public WorkHistory getWorkHistory() { 62 | return workHistory; 63 | } 64 | 65 | public void setWorkHistory(WorkHistory workHistory) { 66 | this.workHistory = workHistory; 67 | } 68 | 69 | public Date getDt() { 70 | return dt; 71 | } 72 | 73 | public void setDt(Date dt) { 74 | this.dt = dt; 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | StringBuilder builder = new StringBuilder(); 80 | builder.append("User [userName="); 81 | builder.append(userName); 82 | builder.append(", password="); 83 | builder.append(password); 84 | builder.append(", age="); 85 | builder.append(age); 86 | builder.append(", gender="); 87 | builder.append(gender); 88 | builder.append(", workHistory="); 89 | builder.append(workHistory); 90 | builder.append("]"); 91 | return builder.toString(); 92 | } 93 | 94 | public class WorkHistory implements Serializable { 95 | 96 | /** 97 | * 98 | */ 99 | private static final long serialVersionUID = 1L; 100 | private String[] workDescriptions; 101 | 102 | private String companyName; 103 | 104 | public String getCompanyName() { 105 | return companyName; 106 | } 107 | 108 | public void setCompanyName(String companyName) { 109 | this.companyName = companyName; 110 | } 111 | 112 | public String[] getWorkDescriptions() { 113 | return workDescriptions; 114 | } 115 | 116 | public void setWorkDescriptions(String[] workDescriptions) { 117 | this.workDescriptions = workDescriptions; 118 | } 119 | 120 | @Override 121 | public String toString() { 122 | StringBuilder builder = new StringBuilder(); 123 | builder.append("WorkHistory [workDescriptions="); 124 | builder.append(Arrays.toString(workDescriptions)); 125 | builder.append("]"); 126 | return builder.toString(); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-provider/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | com.atommiddleware 8 | dubbo-gateway-parent 9 | ${revision} 10 | ../dubbo-gateway-parent/pom.xml 11 | 12 | jar 13 | dubbo-gateway-sample-provider 14 | ${project.artifactId} 15 | The sample provider of dubbo gateway 16 | 17 | 18 | 19 | com.atommiddleware 20 | dubbo-gateway-sample-api 21 | ${project.parent.version} 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter 26 | 27 | 28 | com.alibaba.cloud 29 | spring-cloud-starter-dubbo 30 | 31 | 32 | com.alibaba.spring 33 | spring-context-support 34 | 1.0.11 35 | 36 | 37 | com.alibaba.cloud 38 | spring-cloud-starter-alibaba-nacos-discovery 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-actuator 43 | 44 | 45 | com.alibaba.cloud 46 | spring-cloud-starter-alibaba-nacos-config 47 | 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-maven-plugin 54 | 55 | com.atommiddleware.cloud.sample.provider.App 56 | 57 | ${spring-boot.version} 58 | 59 | 60 | 61 | repackage 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-provider/src/main/java/com/atommiddleware/cloud/sample/provider/App.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.provider; 2 | 3 | import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | /** 8 | * Hello world! 9 | * 10 | */ 11 | @SpringBootApplication 12 | @DubboComponentScan(basePackages = "com.atommiddleware.cloud.sample.provider") 13 | public class App { 14 | public static void main(String[] args) { 15 | SpringApplication.run(App.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-provider/src/main/java/com/atommiddleware/cloud/sample/provider/order/OrderQueryImpl.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.provider.order; 2 | 3 | import org.apache.dubbo.config.annotation.DubboService; 4 | 5 | import com.atommiddleware.cloud.sample.api.Result; 6 | import com.atommiddleware.cloud.sample.api.order.OrderQuery; 7 | 8 | @DubboService 9 | public class OrderQueryImpl implements OrderQuery{ 10 | @Override 11 | public Result getOrder(String orderCode) { 12 | return Result.from().setData("orderCode", orderCode); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-provider/src/main/java/com/atommiddleware/cloud/sample/provider/order/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.provider.order; 2 | 3 | import org.apache.dubbo.config.annotation.DubboService; 4 | 5 | import com.atommiddleware.cloud.sample.api.Result; 6 | import com.atommiddleware.cloud.sample.api.order.OrderService; 7 | @DubboService 8 | public class OrderServiceImpl implements OrderService{ 9 | 10 | @Override 11 | public Result placeOrder(String orderCode) { 12 | return Result.from().setData("notice", "success place order"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-provider/src/main/java/com/atommiddleware/cloud/sample/provider/user/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample.provider.user; 2 | 3 | import org.apache.dubbo.config.annotation.DubboService; 4 | import org.apache.dubbo.rpc.RpcContext; 5 | 6 | import com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.util.internal.ThreadLocalRandom; 7 | import com.atommiddleware.cloud.sample.api.Result; 8 | import com.atommiddleware.cloud.sample.api.user.UserService; 9 | import com.atommiddleware.cloud.sample.api.user.domain.User; 10 | 11 | @DubboService 12 | public class UserServiceImpl implements UserService { 13 | @Override 14 | public Result registerUser(User user) { 15 | System.out.println(RpcContext.getContext().getAttachment("username")); 16 | int time=ThreadLocalRandom.current().nextInt(20, 150); 17 | try { 18 | Thread.sleep(time); 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | System.out.println(user); 23 | return Result.from().setData("user", user); 24 | } 25 | 26 | @Override 27 | public Result registerUserFromHeader(User user) { 28 | System.out.println(user); 29 | return Result.from().setData("user", user); 30 | } 31 | 32 | @Override 33 | public Result registerUserFromCookie(User user) { 34 | System.out.println(user); 35 | return Result.from().setData("user", user); 36 | } 37 | 38 | @Override 39 | public Result registerUserFromPath(User user) { 40 | System.out.println(user); 41 | return Result.from().setData("user", user); 42 | } 43 | 44 | @Override 45 | public Result unRegisterUser(Long userId) { 46 | return Result.from().setData("userId", userId); 47 | } 48 | 49 | @Override 50 | public Result getUserInfo(Long userId, Short gender) { 51 | return Result.from().setData("userId", userId).setData("gender", gender); 52 | } 53 | 54 | @Override 55 | public Result getUserInfo(Long userId, Integer age) { 56 | return Result.from().setData("userId", userId).setData("age", age); 57 | } 58 | 59 | @Override 60 | public Result getUserUserInfoAll(Long userId, Integer age, Long gender, User user) { 61 | System.out.println(user); 62 | return Result.from().setData("userId", userId).setData("age", age).setData("gender", gender).setData("user", 63 | user); 64 | } 65 | 66 | @Override 67 | public Result helloWorld() { 68 | return Result.from().setData("say","helloWorld"); 69 | } 70 | 71 | @Override 72 | public Result getUserInfoFromQueryParamsParamFormatMap(User user) { 73 | System.out.println(user); 74 | return Result.from().setData("user", user); 75 | } 76 | 77 | @Override 78 | public Result getUserInfoFromQueryParamsParamFormatJSON(User user) { 79 | System.out.println(user); 80 | return Result.from().setData("user", user); 81 | } 82 | 83 | @Override 84 | public Result registerUserFromCookieMap(User user) { 85 | System.out.println(user); 86 | return Result.from().setData("user", user); 87 | } 88 | 89 | @Override 90 | public Result registerUserFromPathMap(User user) { 91 | System.out.println(user); 92 | return Result.from().setData("user", user); 93 | } 94 | 95 | @Override 96 | public Result registerUserFromHeaderMap(User user) { 97 | System.out.println(user); 98 | return Result.from().setData("user", user); 99 | } 100 | 101 | @Override 102 | public void helloVoid() { 103 | System.out.println("void"); 104 | } 105 | 106 | @Override 107 | public Result helloWorldPost() { 108 | return Result.from().setData("say","helloWorld post"); 109 | } 110 | 111 | @Override 112 | public void helloVoidPost() { 113 | System.out.println("post void"); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-provider/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: dubbo-gateway-sample-provider 4 | cloud: 5 | nacos: 6 | config: 7 | namespace: dev 8 | prefix: dubbo-gateway-sample-provider 9 | server-addr: 127.0.0.1:8848 10 | file-extension: yml 11 | logging: 12 | file: /mnt/logs -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-consumer/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.3.12.RELEASE 10 | 11 | com.atommiddleware 12 | dubbo-gateway-sample-web-consumer 13 | 0.0.1-SNAPSHOT 14 | jar 15 | 16 | dubbo-gateway-sample-web-consumer 17 | http://maven.apache.org 18 | 19 | 20 | UTF-8 21 | 1.1.4.6-GA 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | com.atommiddleware 31 | dubbo-gateway-sample-api 32 | ${dubbo.gateway.version} 33 | 34 | 35 | org.apache.dubbo 36 | dubbo-spring-boot-starter 37 | 2.7.13 38 | 39 | 40 | org.apache.dubbo 41 | dubbo 42 | 2.7.13 43 | 44 | 45 | org.apache.dubbo 46 | dubbo-registry-nacos 47 | 2.7.13 48 | 49 | 50 | com.alibaba.nacos 51 | nacos-client 52 | 53 | 54 | 55 | 56 | com.alibaba.nacos 57 | nacos-client 58 | 2.0.3 59 | 60 | 61 | com.atommiddleware 62 | dubbo-gateway-spring-boot-starter 63 | ${dubbo.gateway.version} 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-starter-security 68 | 69 | 70 | org.springframework.security 71 | spring-security-cas 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-starter-data-redis 76 | 77 | 78 | org.springframework.session 79 | spring-session-data-redis 80 | 81 | 82 | org.apache.commons 83 | commons-pool2 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-consumer/src/main/java/com/atommiddleware/sample/web/consumer/App.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.sample.web.consumer; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | import com.atommiddleware.cloud.core.annotation.DubboGatewayScanner; 7 | 8 | /** 9 | * Hello world! 10 | * 11 | */ 12 | @SpringBootApplication 13 | @DubboGatewayScanner(basePackages = "com.atommiddleware.cloud.sample.api") 14 | public class App 15 | { 16 | public static void main(String[] args) 17 | { 18 | SpringApplication.run(App.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-consumer/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | com: 2 | atommiddleware: 3 | cloud: 4 | config: 5 | excludUrlPatterns: /cas/redirect 6 | security: 7 | cas: 8 | enable: true 9 | baseUrl: https://cas.atommiddleware.com:8865/cas/redirect?service=https://cas.atommiddleware.com:8865/sample/registerUserFromPathMap/admin/11/1 10 | serverUrl: https://cas.atommiddleware.com:8443/cas 11 | principalAttrs: username,enable 12 | ignoringUrls: 13 | permitUrls: 14 | anonymousUrls: 15 | xss: 16 | enable: true 17 | filterStrategy: 0 18 | filterMode: 0 19 | antisamyFileLocationPattern: 20 | csrf: 21 | enable: true 22 | domain: atommiddleware.com 23 | path: / 24 | cors: 25 | enable: true 26 | allowedOrigins: https://admin.atommiddleware.com:9628,https://cas.atommiddleware.com:8862 27 | allowedHeaders: X-Requested-With,content-type,X-XSRF-TOKEN 28 | allowedMethods: GET,POST 29 | maxAge: 3600 30 | session: 31 | cookie: 32 | domain: atommiddleware.com 33 | name: atomSessionId 34 | path: / 35 | enable: true 36 | dubbo: 37 | application: 38 | name: dubbo-gateway-sample-web-consumer 39 | registry: 40 | address: nacos://127.0.0.1:8848 41 | server: 42 | port: 8865 43 | ssl: 44 | key-password: changeit 45 | key-store: file:D:\secur\atommiddleware.keystore 46 | key-store-password: changeit 47 | spring: 48 | application: 49 | name: dubbo-gateway-sample-web-consumer 50 | redis: 51 | database: 1 52 | host: 127.0.0.1 53 | lettuce: 54 | pool: 55 | max-active: 8 56 | max-idle: 8 57 | max-wait: -1ms 58 | min-idle: 0 59 | port: 6379 60 | timeout: 1s 61 | session: 62 | redis: 63 | flush-mode: on_save 64 | store-type: redis 65 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-provider/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.3.12.RELEASE 10 | 11 | 12 | com.atommiddleware 13 | dubbo-gateway-sample-web-provider 14 | 0.0.1-SNAPSHOT 15 | jar 16 | 17 | dubbo-gateway-sample-web-provider 18 | http://maven.apache.org 19 | 20 | 21 | UTF-8 22 | 1.1.4.6-GA 23 | 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | com.atommiddleware 32 | dubbo-gateway-sample-api 33 | ${dubbo.gateway.version} 34 | 35 | 36 | 37 | org.apache.dubbo 38 | dubbo-spring-boot-starter 39 | 2.7.13 40 | 41 | 42 | org.apache.dubbo 43 | dubbo 44 | 2.7.13 45 | 46 | 47 | 48 | org.apache.dubbo 49 | dubbo-registry-nacos 50 | 2.7.13 51 | 52 | 53 | com.alibaba.nacos 54 | nacos-client 55 | 56 | 57 | 58 | 59 | com.alibaba.nacos 60 | nacos-client 61 | 2.0.3 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-provider/src/main/java/com/atommiddleware/sample/web/provider/App.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.sample.web.provider; 2 | 3 | import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @DubboComponentScan(basePackages = "com.atommiddleware.sample.web.provider") 9 | public class App { 10 | public static void main(String[] args) { 11 | SpringApplication.run(App.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-provider/src/main/java/com/atommiddleware/sample/web/provider/controller/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.sample.web.provider.controller; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class HelloWorldController { 8 | 9 | @GetMapping("/helloWorld") 10 | public String helloWorld() { 11 | return "hello world"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-provider/src/main/java/com/atommiddleware/sample/web/provider/order/OrderQueryImpl.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.sample.web.provider.order; 2 | 3 | import org.apache.dubbo.config.annotation.DubboService; 4 | 5 | import com.atommiddleware.cloud.sample.api.Result; 6 | import com.atommiddleware.cloud.sample.api.order.OrderQuery; 7 | 8 | @DubboService 9 | public class OrderQueryImpl implements OrderQuery{ 10 | @Override 11 | public Result getOrder(String orderCode) { 12 | return Result.from().setData("orderCode", orderCode); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-provider/src/main/java/com/atommiddleware/sample/web/provider/order/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.sample.web.provider.order; 2 | 3 | import org.apache.dubbo.config.annotation.DubboService; 4 | 5 | import com.atommiddleware.cloud.sample.api.Result; 6 | import com.atommiddleware.cloud.sample.api.order.OrderService; 7 | @DubboService 8 | public class OrderServiceImpl implements OrderService{ 9 | 10 | @Override 11 | public Result placeOrder(String orderCode) { 12 | return Result.from().setData("notice", "success place order"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-provider/src/main/java/com/atommiddleware/sample/web/provider/user/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.sample.web.provider.user; 2 | 3 | import org.apache.dubbo.config.annotation.DubboService; 4 | import org.apache.dubbo.rpc.RpcContext; 5 | 6 | import com.atommiddleware.cloud.sample.api.Result; 7 | import com.atommiddleware.cloud.sample.api.user.UserService; 8 | import com.atommiddleware.cloud.sample.api.user.domain.User; 9 | 10 | @DubboService 11 | public class UserServiceImpl implements UserService { 12 | @Override 13 | public Result registerUser(User user) { 14 | System.out.println(RpcContext.getContext().getAttachment("username")); 15 | System.out.println(user); 16 | return Result.from().setData("user", user); 17 | } 18 | 19 | @Override 20 | public Result registerUserFromHeader(User user) { 21 | System.out.println(user); 22 | return Result.from().setData("user", user); 23 | } 24 | 25 | @Override 26 | public Result registerUserFromCookie(User user) { 27 | System.out.println(user); 28 | return Result.from().setData("user", user); 29 | } 30 | 31 | @Override 32 | public Result registerUserFromPath(User user) { 33 | System.out.println(user); 34 | return Result.from().setData("user", user); 35 | } 36 | 37 | @Override 38 | public Result unRegisterUser(Long userId) { 39 | return Result.from().setData("userId", userId); 40 | } 41 | 42 | @Override 43 | public Result getUserInfo(Long userId, Short gender) { 44 | return Result.from().setData("userId", userId).setData("gender", gender); 45 | } 46 | 47 | @Override 48 | public Result getUserInfo(Long userId, Integer age) { 49 | return Result.from().setData("userId", userId).setData("age", age); 50 | } 51 | 52 | @Override 53 | public Result getUserUserInfoAll(Long userId, Integer age, Long gender, User user) { 54 | System.out.println(user); 55 | return Result.from().setData("userId", userId).setData("age", age).setData("gender", gender).setData("user", user); 56 | } 57 | 58 | @Override 59 | public Result helloWorld() { 60 | return Result.from().setData("say","helloWorld"); 61 | } 62 | 63 | @Override 64 | public Result registerUserFromHeaderMap(User user) { 65 | System.out.println(user); 66 | return Result.from().setData("user", user); 67 | } 68 | 69 | @Override 70 | public Result registerUserFromCookieMap(User user) { 71 | System.out.println(user); 72 | return Result.from().setData("user", user); 73 | } 74 | 75 | @Override 76 | public Result registerUserFromPathMap(User user) { 77 | System.out.println(user); 78 | return Result.from().setData("user", user); 79 | } 80 | 81 | @Override 82 | public Result getUserInfoFromQueryParamsParamFormatJSON(User user) { 83 | System.out.println(user); 84 | return Result.from().setData("user", user); 85 | } 86 | 87 | @Override 88 | public Result getUserInfoFromQueryParamsParamFormatMap(User user) { 89 | System.out.println(user); 90 | return Result.from().setData("user", user); 91 | } 92 | 93 | @Override 94 | public void helloVoid() { 95 | System.out.println("void"); 96 | } 97 | 98 | @Override 99 | public Result helloWorldPost() { 100 | return Result.from().setData("say","helloWorld post"); 101 | } 102 | 103 | @Override 104 | public void helloVoidPost() { 105 | System.out.println("helloVoidPost"); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-web-provider/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | dubbo: 2 | application: 3 | name: dubbo-gateway-sample-web-provider 4 | protocol: 5 | name: dubbo 6 | port: 20887 7 | registry: 8 | address: nacos://127.0.0.1:8848 9 | server: 10 | port: 8867 11 | spring: 12 | application: 13 | name: dubbo-gateway-sample-web-provider -------------------------------------------------------------------------------- /dubbo-gateway-sample-zuul/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.atommiddleware 7 | dubbo-gateway-parent 8 | ${revision} 9 | ../dubbo-gateway-parent/pom.xml 10 | 11 | jar 12 | dubbo-gateway-sample-zuul 13 | ${project.artifactId} 14 | The zuul sample of dubbo gateway 15 | 16 | 17 | 18 | com.atommiddleware 19 | dubbo-gateway-spring-boot-starter 20 | ${project.parent.version} 21 | 22 | 23 | com.atommiddleware 24 | dubbo-gateway-sample-api 25 | ${project.parent.version} 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter 30 | 31 | 32 | com.alibaba.cloud 33 | spring-cloud-starter-dubbo 34 | 35 | 36 | com.alibaba.spring 37 | spring-context-support 38 | 1.0.11 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-web 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-actuator 47 | 48 | 49 | org.springframework.cloud 50 | spring-cloud-starter-netflix-zuul 51 | 52 | 53 | com.alibaba.cloud 54 | spring-cloud-starter-alibaba-nacos-discovery 55 | 56 | 57 | com.alibaba.cloud 58 | spring-cloud-starter-alibaba-nacos-config 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-security 63 | 64 | 65 | org.springframework.security 66 | spring-security-cas 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-starter-data-redis 71 | 72 | 73 | org.springframework.session 74 | spring-session-data-redis 75 | 76 | 77 | org.apache.commons 78 | commons-pool2 79 | 80 | 81 | 82 | 83 | 84 | org.springframework.boot 85 | spring-boot-maven-plugin 86 | 87 | com.atommiddleware.cloud.zuul.App 88 | 89 | ${spring-boot.version} 90 | 91 | 92 | 93 | repackage 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-zuul/src/main/java/com/atommiddleware/cloud/zuul/App.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.zuul; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 7 | 8 | import com.atommiddleware.cloud.core.annotation.DubboGatewayScanner; 9 | 10 | @SpringBootApplication 11 | @EnableDiscoveryClient 12 | @EnableZuulProxy 13 | @DubboGatewayScanner(basePackages = "com.atommiddleware.cloud.sample.api") 14 | public class App { 15 | public static void main(String[] args) { 16 | //SendResponseFilter 17 | //ZuulProperties 18 | SpringApplication.run(App.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-zuul/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: dubbo-gateway-sample-zuul 4 | cloud: 5 | nacos: 6 | config: 7 | namespace: dev 8 | prefix: dubbo-gateway-sample-zuul 9 | server-addr: 127.0.0.1:8848 10 | file-extension: yml 11 | logging: 12 | path: /mnt/logs 13 | 14 | com: 15 | atommiddleware: 16 | cloud: 17 | config: 18 | security: 19 | cas: 20 | enable: true 21 | baseUrl: https://cas.atommiddleware.com:8862/cas/redirect?service=https://cas.atommiddleware.com:8862/sample/registerUserFromPathMap/admin/11/1 22 | serverUrl: https://cas.atommiddleware.com:8443/cas 23 | principalAttrs: username,enable 24 | ignoringUrls: 25 | permitUrls: 26 | anonymousUrls: 27 | xss: 28 | enable: true 29 | filterStrategy: 0 30 | filterMode: 0 31 | antisamyFileLocationPattern: 32 | csrf: 33 | enable: true 34 | domain: atommiddleware.com 35 | path: / 36 | cors: 37 | enable: true 38 | allowedOrigins: https://admin.atommiddleware.com:9628,https://cas.atommiddleware.com:8862 39 | allowedHeaders: X-Requested-With,content-type,X-XSRF-TOKEN 40 | allowedMethods: GET,POST 41 | maxAge: 3600 42 | session: 43 | cookie: 44 | domain: atommiddleware.com 45 | name: atomSessionId 46 | path: / 47 | enable: true 48 | -------------------------------------------------------------------------------- /dubbo-gateway-sample-zuul/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallbeanteng/dubbo-gateway/7c32dd44a4ceb43e414993f6bd3c1c0993c881aa/dubbo-gateway-sample-zuul/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /dubbo-gateway-sample/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | com.atommiddleware 8 | dubbo-gateway-parent 9 | ${revision} 10 | ../dubbo-gateway-parent/pom.xml 11 | 12 | jar 13 | dubbo-gateway-sample 14 | ${project.artifactId} 15 | The sample of dubbo gateway 16 | 17 | 18 | 19 | com.atommiddleware 20 | dubbo-gateway-spring-boot-starter 21 | ${project.parent.version} 22 | 23 | 24 | com.atommiddleware 25 | dubbo-gateway-sample-api 26 | ${project.parent.version} 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-starter 31 | 32 | 33 | com.alibaba.cloud 34 | spring-cloud-starter-dubbo 35 | 36 | 37 | com.alibaba.spring 38 | spring-context-support 39 | 1.0.11 40 | 41 | 42 | com.alibaba.cloud 43 | spring-cloud-starter-alibaba-nacos-discovery 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-actuator 48 | 49 | 50 | com.alibaba.cloud 51 | spring-cloud-starter-alibaba-nacos-config 52 | 53 | 54 | org.springframework.cloud 55 | spring-cloud-starter-gateway 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-data-redis-reactive 60 | 61 | 62 | org.springframework.session 63 | spring-session-data-redis 64 | 65 | 66 | org.apache.commons 67 | commons-pool2 68 | 69 | 70 | 71 | 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-maven-plugin 76 | 77 | com.atommiddleware.cloud.sample.App 78 | 79 | ${spring-boot.version} 80 | 81 | 82 | 83 | repackage 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /dubbo-gateway-sample/src/main/java/com/atommiddleware/cloud/sample/App.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.gateway.filter.NettyRoutingFilter; 6 | 7 | import com.atommiddleware.cloud.core.annotation.DubboGatewayScanner; 8 | 9 | /** 10 | * Hello world! 11 | * 12 | */ 13 | @SpringBootApplication 14 | @DubboGatewayScanner(basePackages = "com.atommiddleware.cloud.sample.api") 15 | public class App { 16 | public static void main(String[] args) { 17 | //NettyWriteResponseFilter 18 | //NettyRoutingFilter 19 | SpringApplication.run(App.class, args); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dubbo-gateway-sample/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: dubbo-gateway-sample 4 | cloud: 5 | nacos: 6 | config: 7 | namespace: dev 8 | prefix: dubbo-gateway-sample 9 | server-addr: 127.0.0.1:8848 10 | file-extension: yml 11 | redis: 12 | database: 1 13 | host: 127.0.0.1 14 | lettuce: 15 | pool: 16 | max-active: 8 17 | max-idle: 8 18 | max-wait: -1ms 19 | min-idle: 0 20 | port: 6379 21 | timeout: 1s 22 | session: 23 | redis: 24 | flush-mode: on_save 25 | store-type: redis 26 | logging: 27 | path: /mnt/logs 28 | com: 29 | atommiddleware: 30 | cloud: 31 | config: 32 | excludUrlPatterns: 33 | includUrlPatterns: /sample/*,/order/* 34 | security: 35 | xss: 36 | enable: true 37 | filterStrategy: 0 38 | filterMode: 0 39 | antisamyFileLocationPattern: 40 | csrf: 41 | enable: false 42 | paramCheck: 43 | enable: true 44 | validatorMode: 0 -------------------------------------------------------------------------------- /dubbo-gateway-security/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | com.atommiddleware 8 | dubbo-gateway-parent 9 | ${revision} 10 | ../dubbo-gateway-parent/pom.xml 11 | 12 | jar 13 | dubbo-gateway-security 14 | ${project.artifactId} 15 | The security of dubbo gateway 16 | 17 | 18 | 19 | org.hibernate.validator 20 | hibernate-validator 21 | 22 | 23 | org.springframework 24 | spring-web 25 | true 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-security 30 | true 31 | 32 | 33 | org.springframework.security 34 | spring-security-cas 35 | true 36 | 37 | 38 | javax.servlet 39 | javax.servlet-api 40 | provided 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /dubbo-gateway-security/src/main/java/com/atommiddleware/cloud/security/cas/BasedVoter.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.security.cas; 2 | 3 | import java.util.Collection; 4 | 5 | import org.springframework.security.access.AccessDecisionVoter; 6 | import org.springframework.security.access.ConfigAttribute; 7 | import org.springframework.security.authentication.AuthenticationTrustResolver; 8 | import org.springframework.security.authentication.AuthenticationTrustResolverImpl; 9 | import org.springframework.security.core.Authentication; 10 | import org.springframework.security.core.GrantedAuthority; 11 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 12 | 13 | public class BasedVoter implements AccessDecisionVoter { 14 | 15 | private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl(); 16 | 17 | @Override 18 | public boolean supports(ConfigAttribute attribute) { 19 | return true; 20 | } 21 | 22 | @Override 23 | public boolean supports(Class clazz) { 24 | return true; 25 | } 26 | 27 | @Override 28 | public int vote(Authentication authentication, Object object, Collection attributes) { 29 | int result = ACCESS_DENIED; 30 | if (authenticationTrustResolver.isAnonymous(authentication)) { 31 | return ACCESS_GRANTED; 32 | } 33 | if(null==authentication) { 34 | return result; 35 | } 36 | return vodeHandle(authentication,object,attributes); 37 | 38 | } 39 | 40 | protected int vodeHandle(Authentication authentication, Object object, Collection attributes) { 41 | int result = ACCESS_DENIED; 42 | Collection authorities = extractAuthorities(authentication); 43 | for (GrantedAuthority authority : authorities) { 44 | if (authority instanceof SimpleGrantedAuthority) { 45 | SimpleGrantedAuthority simpleGrantedAuthority = (SimpleGrantedAuthority) authority; 46 | if (simpleGrantedAuthority.getAuthority().equals("ROLE_ADMIN")) { 47 | return ACCESS_GRANTED; 48 | } 49 | } 50 | } 51 | return result; 52 | } 53 | 54 | protected Collection extractAuthorities(Authentication authentication) { 55 | return authentication.getAuthorities(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /dubbo-gateway-security/src/main/java/com/atommiddleware/cloud/security/cas/CustomUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.security.cas; 2 | 3 | import java.util.Map; 4 | 5 | import org.jasig.cas.client.validation.Assertion; 6 | import org.springframework.security.cas.userdetails.AbstractCasAssertionUserDetailsService; 7 | import org.springframework.security.core.authority.AuthorityUtils; 8 | import org.springframework.security.core.userdetails.User; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | 11 | public class CustomUserDetailsService extends AbstractCasAssertionUserDetailsService{ 12 | @Override 13 | protected UserDetails loadUserDetails(Assertion assertion) { 14 | // 可自定义获取用户信息 15 | String username = assertion.getPrincipal().getName(); 16 | Map attributes = assertion.getPrincipal().getAttributes(); 17 | return new User(username, "admin", true, true, 18 | true, true, AuthorityUtils.createAuthorityList("ROLE_ADMIN")); 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /dubbo-gateway-security/src/main/java/com/atommiddleware/cloud/security/cas/PathPatternGrantedAuthority.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.security.cas; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.util.AntPathMatcher; 5 | import org.springframework.util.PathMatcher; 6 | 7 | public class PathPatternGrantedAuthority implements GrantedAuthority{ 8 | 9 | /** 10 | * 11 | */ 12 | private static final long serialVersionUID = 1L; 13 | 14 | private final String pathPattern; 15 | private final static PathMatcher pathMatcher=new AntPathMatcher(); 16 | 17 | public PathPatternGrantedAuthority(String pathPathPattern) { 18 | this.pathPattern=pathPathPattern; 19 | } 20 | 21 | public String getPathPattern() { 22 | return pathPattern; 23 | } 24 | 25 | @Override 26 | public String getAuthority() { 27 | return pathPattern; 28 | } 29 | 30 | public boolean match(String path) { 31 | return pathMatcher.match(pathPattern, path); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /dubbo-gateway-security/src/main/java/com/atommiddleware/cloud/security/cas/PrincipalObtain.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.security.cas; 2 | 3 | import java.util.Map; 4 | 5 | public interface PrincipalObtain { 6 | 7 | Map getPrincipal(); 8 | } 9 | -------------------------------------------------------------------------------- /dubbo-gateway-security/src/main/java/com/atommiddleware/cloud/security/utils/ValidatorUtils.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.security.utils; 2 | 3 | import java.util.Set; 4 | 5 | import javax.validation.ConstraintViolation; 6 | import javax.validation.Validation; 7 | import javax.validation.Validator; 8 | 9 | import org.hibernate.validator.HibernateValidator; 10 | 11 | public class ValidatorUtils { 12 | 13 | private static Validator validatorFast = Validation.byProvider(HibernateValidator.class).configure().failFast(true) 14 | .buildValidatorFactory().getValidator(); 15 | private static Validator validatorAll = Validation.byProvider(HibernateValidator.class).configure().failFast(false) 16 | .buildValidatorFactory().getValidator(); 17 | 18 | public static Set> validateFast(T domain) throws Exception { 19 | Set> validateResult = validatorFast.validate(domain); 20 | return validateResult; 21 | } 22 | 23 | public static Set> validateAll(T domain) throws Exception { 24 | Set> validateResult = validatorAll.validate(domain); 25 | return validateResult; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /dubbo-gateway-security/src/main/java/com/atommiddleware/cloud/security/validation/DefaultParamValidator.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.security.validation; 2 | 3 | import java.util.Iterator; 4 | import java.util.Set; 5 | 6 | import javax.validation.ConstraintViolation; 7 | 8 | import org.springframework.util.CollectionUtils; 9 | 10 | public class DefaultParamValidator implements ParamValidator { 11 | 12 | @Override 13 | public String appendFailReason(Set> validateResult) { 14 | if (!CollectionUtils.isEmpty(validateResult)) { 15 | Iterator> it = validateResult.iterator(); 16 | StringBuilder strErrorBuilder = new StringBuilder(); 17 | while (it.hasNext()) { 18 | ConstraintViolation cv = it.next(); 19 | strErrorBuilder.append(cv.getMessage()+"," ); 20 | } 21 | return strErrorBuilder.toString().substring(0,strErrorBuilder.length() - 1); 22 | } 23 | return null; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /dubbo-gateway-security/src/main/java/com/atommiddleware/cloud/security/validation/ParamValidator.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.security.validation; 2 | 3 | import java.util.Set; 4 | 5 | import javax.validation.ConstraintViolation; 6 | 7 | public interface ParamValidator { 8 | 9 | String appendFailReason(Set> validateResult); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | com.atommiddleware 8 | dubbo-gateway-parent 9 | ${revision} 10 | ../dubbo-gateway-parent/pom.xml 11 | 12 | jar 13 | dubbo-gateway-spring-boot-autoconfigure 14 | ${project.artifactId} 15 | The autoconfigure of dubbo gateway 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-webflux 21 | true 22 | 23 | 24 | com.atommiddleware 25 | dubbo-gateway-core 26 | ${project.parent.version} 27 | 28 | 29 | com.atommiddleware 30 | dubbo-gateway-security 31 | ${project.parent.version} 32 | 33 | 34 | org.projectlombok 35 | lombok 36 | provided 37 | 38 | 39 | javax.servlet 40 | javax.servlet-api 41 | provided 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-starter-gateway 46 | true 47 | 48 | 49 | org.springframework.cloud 50 | spring-cloud-starter-netflix-zuul 51 | true 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-starter-security 56 | true 57 | 58 | 59 | org.springframework.security 60 | spring-security-cas 61 | true 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-starter-data-redis 66 | true 67 | 68 | 69 | org.springframework.session 70 | spring-session-data-redis 71 | true 72 | 73 | 74 | org.apache.commons 75 | commons-pool2 76 | true 77 | 78 | 79 | com.alibaba.cloud 80 | spring-cloud-starter-dubbo 81 | true 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/CasSecurityWebSecurityConfigurerAdapterAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.lang.ArrayUtils; 6 | import org.jasig.cas.client.session.SingleSignOutFilter; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 12 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 13 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 14 | import org.springframework.context.annotation.Configuration; 15 | import org.springframework.security.access.AccessDecisionManager; 16 | import org.springframework.security.cas.web.CasAuthenticationFilter; 17 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 18 | import org.springframework.security.config.annotation.web.builders.WebSecurity; 19 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 20 | import org.springframework.security.web.AuthenticationEntryPoint; 21 | import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; 22 | import org.springframework.security.web.authentication.logout.LogoutFilter; 23 | import org.springframework.security.web.csrf.CsrfTokenRepository; 24 | 25 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 26 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties.CasConfig; 27 | import com.google.common.collect.Lists; 28 | 29 | @Configuration(proxyBeanMethods = false) 30 | @ConditionalOnClass({ WebSecurityConfigurerAdapter.class, CasAuthenticationFilter.class }) 31 | @ConditionalOnWebApplication(type = Type.SERVLET) 32 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config.security.cas", name = "enable", havingValue = "true") 33 | @ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class }) 34 | @AutoConfigureAfter(CasSecurityAutoConfiguration.class) 35 | public class CasSecurityWebSecurityConfigurerAdapterAutoConfiguration extends WebSecurityConfigurerAdapter { 36 | 37 | @Autowired 38 | private SingleSignOutFilter singleSignOutFilter; 39 | @Autowired 40 | private LogoutFilter logoutFilter; 41 | @Autowired 42 | private AuthenticationEntryPoint authenticationEntryPoint; 43 | @Autowired 44 | private CasAuthenticationFilter casAuthenticationFilter; 45 | @Autowired 46 | private DubboReferenceConfigProperties dubboReferenceConfigProperties; 47 | @Autowired 48 | private AccessDecisionManager accessDecisionManager; 49 | @Autowired(required = false) 50 | private CsrfTokenRepository csrfTokenRepository; 51 | @Override 52 | public void configure(WebSecurity web) throws Exception { 53 | List ignoringUrls=Lists.newArrayList("/login/cas","/favicon.ico","/error"); 54 | if (!ArrayUtils.isEmpty(dubboReferenceConfigProperties.getSecurity().getCas().getIgnoringUrls())) { 55 | for(String strIgnoringUrl:dubboReferenceConfigProperties.getSecurity().getCas().getIgnoringUrls()) { 56 | if(!ignoringUrls.contains(strIgnoringUrl)) { 57 | ignoringUrls.add(strIgnoringUrl); 58 | } 59 | } 60 | } 61 | web.ignoring().antMatchers(ignoringUrls.toArray(new String[ignoringUrls.size()])); 62 | super.configure(web); 63 | } 64 | 65 | @Override 66 | protected void configure(HttpSecurity http) throws Exception { 67 | CasConfig casConfig=dubboReferenceConfigProperties.getSecurity().getCas(); 68 | if(dubboReferenceConfigProperties.getSecurity().getCors().isEnable()) { 69 | http.cors(); 70 | }else { 71 | http.cors().disable(); 72 | } 73 | List anonymousUrls=Lists.newArrayList("/login/cas","/favicon.ico","/error"); 74 | if(!ArrayUtils.isEmpty(casConfig.getAnonymousUrls())) { 75 | for(String anonymousUrl:casConfig.getAnonymousUrls()) { 76 | if(!anonymousUrls.contains(anonymousUrl)) { 77 | anonymousUrls.add(anonymousUrl); 78 | } 79 | } 80 | } 81 | http.authorizeRequests().antMatchers(anonymousUrls.toArray(new String[anonymousUrls.size()])).anonymous(); 82 | if(!ArrayUtils.isEmpty(casConfig.getPermitUrls())) { 83 | http.authorizeRequests().antMatchers(casConfig.getPermitUrls()).permitAll(); 84 | } 85 | if (!dubboReferenceConfigProperties.getSecurity().getCsrf().isEnable()) { 86 | http.csrf().disable(); 87 | } 88 | else { 89 | if(null!=csrfTokenRepository) { 90 | http.csrf().csrfTokenRepository(csrfTokenRepository); 91 | } 92 | } 93 | http.authorizeRequests().anyRequest().authenticated().accessDecisionManager(accessDecisionManager).and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and() 94 | .addFilterBefore(casAuthenticationFilter, FilterSecurityInterceptor.class).addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class) 95 | .addFilterBefore(logoutFilter, LogoutFilter.class); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/DubboGateWayApplicationContextInitializer.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import java.util.concurrent.atomic.AtomicBoolean; 4 | 5 | import org.springframework.context.ApplicationContextInitializer; 6 | import org.springframework.context.ConfigurableApplicationContext; 7 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 8 | 9 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 10 | 11 | public class DubboGateWayApplicationContextInitializer 12 | implements ApplicationContextInitializer { 13 | 14 | private static AtomicBoolean atomicb=new AtomicBoolean(false); 15 | 16 | @Override 17 | public void initialize(ConfigurableApplicationContext applicationContext) { 18 | if (atomicb.compareAndSet(false, true)) { 19 | AnnotationConfigApplicationContext annotationConfigApplicationContext = createContext(applicationContext); 20 | DubboReferenceConfigProperties dubboReferenceConfigProperties = annotationConfigApplicationContext 21 | .getBean(DubboReferenceConfigProperties.class); 22 | applicationContext.getBeanFactory().registerSingleton( 23 | DubboReferenceConfigProperties.class.getName(), dubboReferenceConfigProperties); 24 | } 25 | } 26 | 27 | protected AnnotationConfigApplicationContext createContext( 28 | ConfigurableApplicationContext parentApplicationContext) { 29 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 30 | context.setEnvironment(parentApplicationContext.getEnvironment()); 31 | context.setClassLoader(parentApplicationContext.getClassLoader()); 32 | context.register(DubboGatewayBootstrapConfiguration.class); 33 | context.refresh(); 34 | return context; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/DubboGatewayAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import org.apache.dubbo.config.annotation.DubboReference; 4 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 10 | import org.springframework.cloud.gateway.filter.GlobalFilter; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.http.codec.ServerCodecConfigurer; 14 | import org.springframework.util.PathMatcher; 15 | 16 | import com.atommiddleware.cloud.core.annotation.DefaultResponseResult; 17 | import com.atommiddleware.cloud.core.annotation.ResponseReactiveResult; 18 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 19 | import com.atommiddleware.cloud.core.filter.DubboGlobalFilter; 20 | import com.atommiddleware.cloud.core.serialize.Serialization; 21 | 22 | @Configuration(proxyBeanMethods = false) 23 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config", name = "enable", havingValue = "true", matchIfMissing = true) 24 | @AutoConfigureAfter(DubboGatewayCommonAutoConfiguration.class) 25 | @ConditionalOnWebApplication(type = Type.REACTIVE) 26 | @ConditionalOnClass({ GlobalFilter.class, DubboReference.class }) 27 | public class DubboGatewayAutoConfiguration { 28 | 29 | @Bean 30 | @ConditionalOnMissingBean 31 | public ResponseReactiveResult responseResult(DubboReferenceConfigProperties dubboReferenceConfigProperties) { 32 | return new DefaultResponseResult(dubboReferenceConfigProperties); 33 | } 34 | 35 | @Bean 36 | @ConditionalOnMissingBean 37 | public DubboGlobalFilter dubboGlobalFilter(ServerCodecConfigurer serverCodecConfigurer, 38 | DubboReferenceConfigProperties dubboReferenceConfigProperties, ResponseReactiveResult responseResult, 39 | Serialization serialization, PathMatcher pathMatcher) { 40 | return new DubboGlobalFilter(pathMatcher, serialization, dubboReferenceConfigProperties, serverCodecConfigurer, 41 | responseResult); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/DubboGatewayBootstrapConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 7 | @Configuration(proxyBeanMethods = false) 8 | @EnableConfigurationProperties(DubboReferenceConfigProperties.class) 9 | public class DubboGatewayBootstrapConfiguration { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/DubboGatewayCommonAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.core.io.ResourceLoader; 10 | import org.springframework.util.AntPathMatcher; 11 | import org.springframework.util.PathMatcher; 12 | 13 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 14 | import com.atommiddleware.cloud.core.security.DefaultXssSecurity; 15 | import com.atommiddleware.cloud.core.security.EncodeHtmlXssSecurity; 16 | import com.atommiddleware.cloud.core.security.EsapiEncodeHtmlXssSecurity; 17 | import com.atommiddleware.cloud.core.security.XssSecurity; 18 | import com.atommiddleware.cloud.core.security.XssSecurity.XssFilterStrategy; 19 | import com.atommiddleware.cloud.core.serialize.JacksonSerialization; 20 | import com.atommiddleware.cloud.core.serialize.Serialization; 21 | import com.atommiddleware.cloud.security.validation.DefaultParamValidator; 22 | import com.atommiddleware.cloud.security.validation.ParamValidator; 23 | 24 | @Configuration(proxyBeanMethods = false) 25 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config", name = "enable", havingValue = "true", matchIfMissing = true) 26 | @AutoConfigureAfter(name = "org.springframework.cloud.gateway.config.GatewayAutoConfiguration") 27 | public class DubboGatewayCommonAutoConfiguration { 28 | 29 | @Bean 30 | @ConditionalOnMissingBean 31 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config.security.xss", name = "filterMode", havingValue = "0", matchIfMissing = true) 32 | public XssSecurity xssSecurityEsapiEncodeHtml() { 33 | return new EsapiEncodeHtmlXssSecurity(); 34 | } 35 | 36 | @Bean 37 | @ConditionalOnMissingBean 38 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config.security.xss", name = "filterMode", havingValue = "1") 39 | public XssSecurity xssSecurity(ResourceLoader resourceLoader, 40 | DubboReferenceConfigProperties dubboReferenceConfigProperties) { 41 | return new DefaultXssSecurity(resourceLoader, 42 | dubboReferenceConfigProperties.getSecurity().getXss().getAntisamyFileLocationPattern()); 43 | } 44 | 45 | @Bean 46 | @ConditionalOnMissingBean 47 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config.security.xss", name = "filterMode", havingValue = "2") 48 | public XssSecurity xssSecurityEncodeHtml() { 49 | return new EncodeHtmlXssSecurity(); 50 | } 51 | 52 | @Bean 53 | @ConditionalOnMissingBean 54 | public Serialization serialization(DubboReferenceConfigProperties dubboReferenceConfigProperties, 55 | XssSecurity xssSecurity) { 56 | return new JacksonSerialization(dubboReferenceConfigProperties.getSecurity().getXss().isEnable(), xssSecurity, 57 | XssFilterStrategy.values()[dubboReferenceConfigProperties.getSecurity().getXss().getFilterStrategy()]); 58 | } 59 | 60 | @Bean 61 | @ConditionalOnMissingBean 62 | public PathMatcher pathMatcher() { 63 | return new AntPathMatcher(); 64 | } 65 | 66 | @Bean 67 | @ConditionalOnMissingBean 68 | @ConditionalOnClass(name = "javax.validation.ConstraintViolationException") 69 | public ParamValidator paramValidator() { 70 | return new DefaultParamValidator(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/DubboGatewayServletAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import org.apache.dubbo.config.annotation.DubboReference; 4 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 11 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.Import; 15 | import org.springframework.core.Ordered; 16 | import org.springframework.util.PathMatcher; 17 | 18 | import com.atommiddleware.cloud.core.annotation.DefaultResponseServletResult; 19 | import com.atommiddleware.cloud.core.annotation.ResponseServletResult; 20 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 21 | import com.atommiddleware.cloud.core.filter.DubboServletFilter; 22 | import com.atommiddleware.cloud.core.filter.ServletErrorFilter; 23 | import com.atommiddleware.cloud.core.serialize.Serialization; 24 | import com.atommiddleware.cloud.security.validation.ParamValidator; 25 | 26 | @Configuration(proxyBeanMethods = false) 27 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config", name = "enable", havingValue = "true", matchIfMissing = true) 28 | @ConditionalOnWebApplication(type = Type.SERVLET) 29 | @ConditionalOnMissingClass(value = { "com.netflix.zuul.http.ZuulServlet", "com.netflix.zuul.http.ZuulServletFilter" }) 30 | @AutoConfigureAfter(DubboGatewayCommonAutoConfiguration.class) 31 | @ConditionalOnClass({DubboReference.class}) 32 | @Import(SevlertImportBeanDefinitionRegistrar.class) 33 | public class DubboGatewayServletAutoConfiguration { 34 | 35 | @Bean 36 | @ConditionalOnMissingBean 37 | public ResponseServletResult responseResult(DubboReferenceConfigProperties dubboReferenceConfigProperties, 38 | Serialization serialization) { 39 | return new DefaultResponseServletResult(dubboReferenceConfigProperties, serialization); 40 | } 41 | 42 | @Bean("registerDubboGatewayFilter") 43 | @ConditionalOnMissingBean(name = "registerDubboGatewayFilter") 44 | public FilterRegistrationBean registerDubboGatewayFilter( 45 | DubboReferenceConfigProperties dubboReferenceConfigProperties, PathMatcher pathMatcher, 46 | Serialization serialization, ResponseServletResult responseResult,ParamValidator paramValidator) { 47 | FilterRegistrationBean registration = new FilterRegistrationBean(); 48 | registration.setFilter( 49 | new DubboServletFilter(pathMatcher, serialization, 50 | responseResult, dubboReferenceConfigProperties.getExcludUrlPatterns(),paramValidator)); 51 | if (null != dubboReferenceConfigProperties.getIncludUrlPatterns() 52 | && dubboReferenceConfigProperties.getIncludUrlPatterns().length > 0) { 53 | registration.addUrlPatterns(dubboReferenceConfigProperties.getIncludUrlPatterns()); 54 | } 55 | registration.setName("dubboGatewayFilter"); 56 | registration.setOrder(dubboReferenceConfigProperties.getFilterOrder()); 57 | return registration; 58 | } 59 | 60 | @Bean("registerServletErrorFilter") 61 | @ConditionalOnMissingBean(name = "registerServletErrorFilter") 62 | public FilterRegistrationBean registerServletErrorFilter( 63 | DubboReferenceConfigProperties dubboReferenceConfigProperties, PathMatcher pathMatcher, 64 | Serialization serialization, ResponseServletResult responseResult) { 65 | FilterRegistrationBean registration = new FilterRegistrationBean(); 66 | registration.setFilter(new ServletErrorFilter(responseResult)); 67 | registration.setName("servletErrorFilter"); 68 | registration.setOrder(Ordered.HIGHEST_PRECEDENCE - 50); 69 | return registration; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/DubboGatewayZuulServletAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import org.apache.dubbo.config.annotation.DubboReference; 4 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 10 | import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.context.annotation.Import; 14 | import org.springframework.util.PathMatcher; 15 | 16 | import com.atommiddleware.cloud.core.annotation.DefaultResponseZuulServletResult; 17 | import com.atommiddleware.cloud.core.annotation.ResponseZuulServletResult; 18 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 19 | import com.atommiddleware.cloud.core.filter.DubboServletZuulFilter; 20 | import com.atommiddleware.cloud.core.filter.ZuulErrorFilter; 21 | import com.atommiddleware.cloud.core.serialize.Serialization; 22 | import com.atommiddleware.cloud.security.validation.ParamValidator; 23 | import com.netflix.zuul.filters.ZuulServletFilter; 24 | import com.netflix.zuul.http.ZuulServlet; 25 | 26 | @Configuration(proxyBeanMethods = false) 27 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config", name = "enable", havingValue = "true", matchIfMissing = true) 28 | @ConditionalOnWebApplication(type = Type.SERVLET) 29 | @ConditionalOnClass({ ZuulServlet.class, ZuulServletFilter.class,DubboReference.class }) 30 | @AutoConfigureAfter(DubboGatewayCommonAutoConfiguration.class) 31 | @Import(SevlertImportBeanDefinitionRegistrar.class) 32 | public class DubboGatewayZuulServletAutoConfiguration { 33 | 34 | @Bean 35 | @ConditionalOnMissingBean 36 | public ResponseZuulServletResult responseZuulServletResult( 37 | DubboReferenceConfigProperties dubboReferenceConfigProperties, Serialization serialization) { 38 | return new DefaultResponseZuulServletResult(dubboReferenceConfigProperties, serialization); 39 | } 40 | 41 | @Bean 42 | @ConditionalOnMissingBean 43 | public DubboServletZuulFilter dubboServletZuulFilter(PathMatcher pathMatcher, Serialization serialization, 44 | ResponseZuulServletResult responseZuulServletResult, ZuulProperties properties, 45 | ParamValidator paramValidator) { 46 | return new DubboServletZuulFilter(pathMatcher, serialization, responseZuulServletResult, paramValidator); 47 | } 48 | 49 | @Bean 50 | @ConditionalOnMissingBean 51 | public ZuulErrorFilter dubboZuulErrorFilter(ResponseZuulServletResult responseZuulServletResult) { 52 | return new ZuulErrorFilter(responseZuulServletResult); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/ExceptionHandlerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import org.springframework.beans.factory.ObjectProvider; 7 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 11 | import org.springframework.boot.autoconfigure.web.ResourceProperties; 12 | import org.springframework.boot.autoconfigure.web.ServerProperties; 13 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 14 | import org.springframework.boot.web.reactive.error.ErrorAttributes; 15 | import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; 16 | import org.springframework.context.ApplicationContext; 17 | import org.springframework.context.annotation.Bean; 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.core.Ordered; 20 | import org.springframework.core.annotation.Order; 21 | import org.springframework.http.codec.ServerCodecConfigurer; 22 | import org.springframework.web.reactive.result.view.ViewResolver; 23 | 24 | import com.atommiddleware.cloud.core.exception.JsonExceptionHandler; 25 | import com.atommiddleware.cloud.security.validation.ParamValidator; 26 | 27 | @Configuration(proxyBeanMethods = false) 28 | @EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class}) 29 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config", name = "enable", havingValue = "true", matchIfMissing = true) 30 | @AutoConfigureAfter(DubboGatewayAutoConfiguration.class) 31 | @ConditionalOnWebApplication(type = Type.REACTIVE) 32 | public class ExceptionHandlerConfiguration { 33 | 34 | private final ServerProperties serverProperties; 35 | 36 | private final ApplicationContext applicationContext; 37 | 38 | private final ResourceProperties resourceProperties; 39 | 40 | private final List viewResolvers; 41 | 42 | private final ServerCodecConfigurer serverCodecConfigurer; 43 | 44 | private final ParamValidator paramValidator; 45 | public ExceptionHandlerConfiguration(ServerProperties serverProperties, 46 | ResourceProperties resourceProperties, 47 | ObjectProvider> viewResolversProvider, 48 | ServerCodecConfigurer serverCodecConfigurer, 49 | ApplicationContext applicationContext,ParamValidator paramValidator) { 50 | this.serverProperties = serverProperties; 51 | this.applicationContext = applicationContext; 52 | this.resourceProperties = resourceProperties; 53 | this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); 54 | this.serverCodecConfigurer = serverCodecConfigurer; 55 | this.paramValidator=paramValidator; 56 | } 57 | 58 | @Bean 59 | @Order(Ordered.HIGHEST_PRECEDENCE) 60 | public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) { 61 | JsonExceptionHandler exceptionHandler = new JsonExceptionHandler( 62 | errorAttributes, 63 | this.resourceProperties, 64 | this.serverProperties.getError(), 65 | this.applicationContext,this.paramValidator); 66 | exceptionHandler.setViewResolvers(this.viewResolvers); 67 | exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters()); 68 | exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders()); 69 | return exceptionHandler; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/RedisHttpSessionAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 12 | import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession; 13 | import org.springframework.session.web.http.CookieSerializer; 14 | import org.springframework.session.web.http.DefaultCookieSerializer; 15 | import org.springframework.util.StringUtils; 16 | import org.springframework.web.server.session.CookieWebSessionIdResolver; 17 | import org.springframework.web.server.session.WebSessionIdResolver; 18 | 19 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties; 20 | import com.atommiddleware.cloud.core.config.DubboReferenceConfigProperties.RedisHttpSessionConfig.CookieConfig; 21 | 22 | @Configuration(proxyBeanMethods = false) 23 | @ConditionalOnClass(CookieSerializer.class) 24 | @ConditionalOnProperty(prefix = "com.atommiddleware.cloud.config.session.cookie", name = "enable", havingValue = "true") 25 | @AutoConfigureAfter(DubboGatewayCommonAutoConfiguration.class) 26 | public class RedisHttpSessionAutoConfiguration { 27 | 28 | @Configuration 29 | @EnableRedisHttpSession 30 | @ConditionalOnWebApplication(type = Type.SERVLET) 31 | class SevlertRedisHttpSessionConfiguration { 32 | @Bean 33 | @ConditionalOnMissingBean 34 | public CookieSerializer cookieSerializer(DubboReferenceConfigProperties dubboReferenceConfigProperties) { 35 | DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer(); 36 | CookieConfig cookieConfig=dubboReferenceConfigProperties.getSession().getCookie(); 37 | if (!StringUtils.isEmpty(cookieConfig.getName())) { 38 | defaultCookieSerializer 39 | .setCookieName(cookieConfig.getName()); 40 | } 41 | if (!StringUtils.isEmpty(cookieConfig.getDomain())) { 42 | defaultCookieSerializer 43 | .setDomainName(cookieConfig.getDomain()); 44 | } 45 | if (!StringUtils.isEmpty(cookieConfig.getPath())) { 46 | defaultCookieSerializer 47 | .setCookiePath(cookieConfig.getPath()); 48 | } 49 | return defaultCookieSerializer; 50 | } 51 | } 52 | 53 | @Configuration 54 | @EnableRedisWebSession 55 | @ConditionalOnWebApplication(type = Type.REACTIVE) 56 | class ReactiveRedisHttpSessionConfiguration { 57 | 58 | @Bean 59 | @ConditionalOnMissingBean 60 | public WebSessionIdResolver webSessionIdResolver( 61 | DubboReferenceConfigProperties dubboReferenceConfigProperties) { 62 | CookieWebSessionIdResolver resolver = new CookieWebSessionIdResolver(); 63 | CookieConfig cookieConfig=dubboReferenceConfigProperties.getSession().getCookie(); 64 | resolver.addCookieInitializer(o -> { 65 | if (!StringUtils.isEmpty(cookieConfig.getDomain())) { 66 | o.domain(cookieConfig.getDomain()); 67 | } 68 | if (!StringUtils.isEmpty(cookieConfig.getPath())) { 69 | o.path(cookieConfig.getPath()); 70 | } 71 | }); 72 | if (!StringUtils.isEmpty(cookieConfig.getName())) { 73 | resolver.setCookieName(cookieConfig.getName()); 74 | } 75 | return resolver; 76 | } 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/java/com/atommiddleware/cloud/autoconfigure/SevlertImportBeanDefinitionRegistrar.java: -------------------------------------------------------------------------------- 1 | package com.atommiddleware.cloud.autoconfigure; 2 | 3 | import org.springframework.beans.factory.support.BeanDefinitionBuilder; 4 | import org.springframework.beans.factory.support.BeanDefinitionRegistry; 5 | import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; 6 | import org.springframework.core.type.AnnotationMetadata; 7 | 8 | import com.atommiddleware.cloud.core.controller.ForwardingServiceController; 9 | 10 | public class SevlertImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { 11 | @Override 12 | public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 13 | registry.registerBeanDefinition(ForwardingServiceController.class.getSimpleName(), 14 | BeanDefinitionBuilder.genericBeanDefinition(ForwardingServiceController.class).getBeanDefinition()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/resources/META-INF/spring-autoconfigure-metadata.properties: -------------------------------------------------------------------------------- 1 | com.atommiddleware.cloud.autoconfigure.DubboGatewayCommonAutoConfiguration= 2 | com.atommiddleware.cloud.autoconfigure.DubboGatewayCommonAutoConfiguration.AutoConfigureAfter=org.springframework.cloud.gateway.config.GatewayAutoConfiguration 3 | com.atommiddleware.cloud.autoconfigure.DubboGatewayAutoConfiguration= 4 | com.atommiddleware.cloud.autoconfigure.DubboGatewayAutoConfiguration.AutoConfigureAfter=com.atommiddleware.cloud.autoconfigure.DubboGatewayCommonAutoConfiguration 5 | com.atommiddleware.cloud.autoconfigure.DubboGatewayAutoConfiguration.ConditionalOnClass=org.springframework.cloud.gateway.filter.GlobalFilter,org.apache.dubbo.config.annotation.DubboReference 6 | com.atommiddleware.cloud.autoconfigure.ExceptionHandlerConfiguration= 7 | com.atommiddleware.cloud.autoconfigure.ExceptionHandlerConfiguration.AutoConfigureAfter=com.atommiddleware.cloud.autoconfigure.DubboGatewayAutoConfiguration 8 | com.atommiddleware.cloud.autoconfigure.ExceptionHandlerConfiguration.ConditionalOnClass=org.springframework.cloud.gateway.filter.GlobalFilter 9 | com.atommiddleware.cloud.autoconfigure.DubboGatewayServletAutoConfiguration= 10 | com.atommiddleware.cloud.autoconfigure.DubboGatewayServletAutoConfiguration.AutoConfigureAfter=com.atommiddleware.cloud.autoconfigure.DubboGatewayCommonAutoConfiguration 11 | com.atommiddleware.cloud.autoconfigure.DubboGatewayServletAutoConfiguration.ConditionalOnClass=org.apache.dubbo.config.annotation.DubboReference 12 | com.atommiddleware.cloud.autoconfigure.DubboGatewayZuulServletAutoConfiguration= 13 | com.atommiddleware.cloud.autoconfigure.DubboGatewayZuulServletAutoConfiguration.AutoConfigureAfter=com.atommiddleware.cloud.autoconfigure.DubboGatewayCommonAutoConfiguration 14 | com.atommiddleware.cloud.autoconfigure.DubboGatewayZuulServletAutoConfiguration.ConditionalOnClass=com.netflix.zuul.http.ZuulServlet,com.netflix.zuul.filters.ZuulServletFilter,org.apache.dubbo.config.annotation.DubboReference 15 | com.atommiddleware.cloud.autoconfigure.CasSecurityAutoConfiguration= 16 | com.atommiddleware.cloud.autoconfigure.CasSecurityAutoConfiguration.AutoConfigureAfter=com.atommiddleware.cloud.autoconfigure.DubboGatewayCommonAutoConfiguration 17 | com.atommiddleware.cloud.autoconfigure.CasSecurityAutoConfiguration.ConditionalOnClass=org.springframework.security.cas.web.CasAuthenticationFilter 18 | com.atommiddleware.cloud.autoconfigure.CasSecurityWebSecurityConfigurerAdapterAutoConfiguration= 19 | com.atommiddleware.cloud.autoconfigure.CasSecurityWebSecurityConfigurerAdapterAutoConfiguration.AutoConfigureAfter=com.atommiddleware.cloud.autoconfigure.CasSecurityAutoConfiguration 20 | com.atommiddleware.cloud.autoconfigure.CasSecurityWebSecurityConfigurerAdapterAutoConfiguration.ConditionalOnClass=org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter,org.springframework.security.cas.web.CasAuthenticationFilter 21 | com.atommiddleware.cloud.autoconfigure.RedisHttpSessionAutoConfiguration= 22 | com.atommiddleware.cloud.autoconfigure.RedisHttpSessionAutoConfiguration.AutoConfigureAfter=com.atommiddleware.cloud.autoconfigure.DubboGatewayCommonAutoConfiguration 23 | com.atommiddleware.cloud.autoconfigure.RedisHttpSessionAutoConfiguration.ConditionalOnClass=org.springframework.session.web.http.CookieSerializer 24 | 25 | 26 | -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | com.atommiddleware.cloud.autoconfigure.DubboGatewayCommonAutoConfiguration,\ 3 | com.atommiddleware.cloud.autoconfigure.DubboGatewayAutoConfiguration,\ 4 | com.atommiddleware.cloud.autoconfigure.ExceptionHandlerConfiguration,\ 5 | com.atommiddleware.cloud.autoconfigure.DubboGatewayServletAutoConfiguration,\ 6 | com.atommiddleware.cloud.autoconfigure.DubboGatewayZuulServletAutoConfiguration,\ 7 | com.atommiddleware.cloud.autoconfigure.CasSecurityAutoConfiguration,\ 8 | com.atommiddleware.cloud.autoconfigure.CasSecurityWebSecurityConfigurerAdapterAutoConfiguration,\ 9 | com.atommiddleware.cloud.autoconfigure.RedisHttpSessionAutoConfiguration 10 | # Bootstrap components 11 | # org.springframework.cloud.bootstrap.BootstrapConfiguration=\ 12 | # com.atommiddleware.cloud.autoconfigure.DubboGatewayBootstrapConfiguration 13 | # Application Listeners 14 | org.springframework.context.ApplicationListener=\ 15 | com.atommiddleware.cloud.core.annotation.DubboGateWayApplicationListener 16 | # DubboApiWrapperFactory 17 | com.atommiddleware.cloud.core.annotation.DubboApiWrapperFactory=\ 18 | com.atommiddleware.cloud.core.annotation.DefaultDubboApiWrapperFactory 19 | # DubboGateWayApplicationContextInitializer 20 | org.springframework.context.ApplicationContextInitializer=\ 21 | com.atommiddleware.cloud.autoconfigure.DubboGateWayApplicationContextInitializer -------------------------------------------------------------------------------- /dubbo-gateway-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | com.atommiddleware 8 | dubbo-gateway-parent 9 | ${revision} 10 | ../dubbo-gateway-parent/pom.xml 11 | 12 | jar 13 | dubbo-gateway-spring-boot-starter 14 | ${project.artifactId} 15 | The starter of dubbo gateway 16 | 17 | 18 | 19 | com.atommiddleware 20 | dubbo-gateway-spring-boot-autoconfigure 21 | ${project.parent.version} 22 | 23 | 24 | 25 | --------------------------------------------------------------------------------