Эх сурвалжийг харах

fix: 修改 Keycloak 集成方式

liangke 4 жил өмнө
parent
commit
0a91ff2ba5

+ 43 - 15
pom.xml

@@ -18,32 +18,31 @@
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-gateway</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-loadbalancer</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.alibaba.csp</groupId>
             <artifactId>sentinel-datasource-nacos</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
@@ -58,24 +57,53 @@
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.security.oauth.boot</groupId>
-            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-spring-boot-starter</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-oauth2-client</artifactId>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
         </dependency>
         <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-oauth2-jose</artifactId>
+            <groupId>com.alibaba.cola</groupId>
+            <artifactId>cola-component-dto</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-spring-boot-starter</artifactId>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-authz-client</artifactId>
+            <groupId>com.github.ben-manes.caffeine</groupId>
+            <artifactId>caffeine</artifactId>
         </dependency>
     </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <layers>
+                        <enabled>true</enabled>
+                    </layers>
+                    <executable>true</executable>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>

+ 2 - 1
src/main/java/com/inspur/smsb/gateway/SmsbGatewayApplication.java

@@ -2,6 +2,7 @@ package com.inspur.smsb.gateway;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 
 /**
@@ -10,7 +11,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  * @author liangke
  */
 @EnableDiscoveryClient
-@SpringBootApplication
+@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
 public class SmsbGatewayApplication {
     public static void main(String[] args) {
         SpringApplication.run(SmsbGatewayApplication.class, args);

+ 0 - 25
src/main/java/com/inspur/smsb/gateway/config/HomeController.java

@@ -1,25 +0,0 @@
-package com.inspur.smsb.gateway.config;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * @author liangke
- */
-@RestController
-public class HomeController {
-    @RequestMapping("/")
-    public String index() {
-        return "index";
-    }
-
-    @RequestMapping("/customer")
-    public String customer() {
-        return "only customer can see";
-    }
-
-    @RequestMapping("/admin")
-    public String admin() {
-        return "only admin cas see";
-    }
-}

+ 11 - 8
src/main/java/com/inspur/smsb/gateway/config/KeycloakSecurityConfig.java

@@ -7,7 +7,7 @@ import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurer
 import org.springframework.context.annotation.Bean;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
 import org.springframework.security.core.session.SessionRegistryImpl;
 import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
 import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@@ -19,8 +19,8 @@ import javax.annotation.Resource;
  *
  * @author liangke
  */
-@EnableWebSecurity(debug = true)
 @KeycloakConfiguration
+@EnableWebFluxSecurity
 public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
     /**
      * Registers the KeycloakAuthenticationProvider with the authentication manager.
@@ -48,12 +48,15 @@ public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter
     }
 
     @Override
-    protected void configure(HttpSecurity http) throws Exception {
-        super.configure(http);
-        http.csrf().disable()
-            .authorizeRequests()
-            .antMatchers("/customer/**").hasRole("CUSTOMER")
-            .antMatchers("/admin/**").hasAnyRole("ADMIN")
+    protected void configure(HttpSecurity httpSecurity) throws Exception {
+        super.configure(httpSecurity);
+        httpSecurity.csrf().disable();
+        httpSecurity.httpBasic().disable();
+        httpSecurity.formLogin().disable();
+        httpSecurity.authorizeRequests().antMatchers("/device/**",
+                "/deviceGroup/**", "/product/**", "/productType/**",
+                "/qualification/**", "/region/**", "/minio-data/**", "/item/**", "/scheduling-config/**", "/scheduling/**",
+                "/scheduling-plugin-device/**").hasAnyRole("operation-staff", "operation-supervisor")
             .anyRequest().permitAll();
     }
 }

+ 65 - 0
src/main/java/com/inspur/smsb/gateway/handler/GatewayExceptionHandler.java

@@ -0,0 +1,65 @@
+package com.inspur.smsb.gateway.handler;
+
+import com.alibaba.cola.dto.Response;
+import com.alibaba.fastjson.JSON;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
+import org.springframework.cloud.gateway.support.NotFoundException;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.io.buffer.DataBufferFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.lang.NonNull;
+import org.springframework.web.server.ResponseStatusException;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+/**
+ * 网关统一异常处理
+ *
+ * @author liangke
+ */
+@Slf4j
+@Configuration
+@Order(-1)
+@RequiredArgsConstructor
+public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
+    /**
+     * @param exchange exchange
+     * @param ex       ex
+     * @return Mono<Void>
+     */
+    @NonNull
+    @Override
+    public Mono<Void> handle(ServerWebExchange exchange, @NonNull Throwable ex) {
+        ServerHttpResponse response = exchange.getResponse();
+
+        if (exchange.getResponse().isCommitted()) {
+            return Mono.error(ex);
+        }
+
+        String msg;
+
+        if (ex instanceof NotFoundException) {
+            msg = "服务未找到";
+        } else if (ex instanceof ResponseStatusException) {
+            ResponseStatusException responseStatusException = (ResponseStatusException) ex;
+            msg = responseStatusException.getMessage();
+        } else {
+            msg = "内部服务器错误";
+        }
+
+        log.error("[网关异常处理]请求方法:{},请求路径: {},异常信息: {}", exchange.getRequest().getMethod(), exchange.getRequest().getPath(), ex.getMessage());
+
+        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+        response.setStatusCode(HttpStatus.OK);
+
+        return response.writeWith(Mono.fromSupplier(() -> {
+            DataBufferFactory bufferFactory = response.bufferFactory();
+            return bufferFactory.wrap(JSON.toJSONBytes(Response.buildFailure("500", msg)));
+        }));
+    }
+}

+ 43 - 5
src/main/resources/application.yml

@@ -6,15 +6,13 @@ spring:
     name: smsb-gateway
   main:
     allow-bean-definition-overriding: true
+    web-application-type: reactive
   cloud:
     nacos:
       server-addr: 10.180.88.84:8060
       config:
         file-extension: yml
         refresh-enabled: true
-        namespace: a16fbead-fe72-45aa-b61c-45a2b9eddbb2
-      discovery:
-        namespace: a16fbead-fe72-45aa-b61c-45a2b9eddbb2
       username: nacos
       password: inspur-nacos
     sentinel:
@@ -23,14 +21,54 @@ spring:
         dashboard: localhost:8080
       filter:
         enabled: false
+    gateway:
+      discovery:
+        locator:
+          enabled: true
+          lower-case-service-id: true
+      routes:
+        - id: device-manager-web
+          uri: lb://device-manager-web
+          predicates:
+            - Path=/device/**,/deviceGroup/**,/product/**,/productType/**,/qualification/**,/region/**
+        - id: smsb-oss-dubbo-consumer
+          uri: lb://smsb-oss-dubbo-consumer
+          predicates:
+            - Path=/minio-data/**
+        - id: smsb-content-dubbo-consumer
+          uri: lb://smsb-content-dubbo-consumer
+          predicates:
+            - Path=/item/**,/scheduling-config/**,/scheduling/**,/scheduling-plugin-device/**
+  cache:
+    type: caffeine
+    cache-names: smsb-gateway
+    caffeine:
+      spec: maximumSize=5000,expireAfterAccess=3600s
+  redis:
+    database: 5
+    sentinel:
+      master: mymaster
+      password: 666666
+      nodes:
+        - 10.180.88.84:27001
+        - 10.180.88.84:27002
+        - 10.180.88.84:27003
+    password: 666666
+    timeout: 6000ms
+    lettuce:
+      pool:
+        max-active: 1000
+        max-wait: -1ms
+        max-idle: 10
+        min-idle: 5
 
 keycloak:
-  auth-server-url: http://liangke00.home.langchao.com:18080/
   realm: smsb
+  auth-server-url: http://liangke00.home.langchao.com:18080/auth
   resource: backend-api
   ssl-required: external
   credentials:
     secret: 0ed56548-885a-471d-9efa-c3e5f03f5529
-  bearer-only: true
+  bearer-only: false
   use-resource-role-mappings: false
   cors: true