Ver Fonte

actuator and /swagger-ui 安全性增强

"/actuator","/actuator/**","/swagger-ui","/swagger-ui/**"
shimingxy há 1 mês atrás
pai
commit
c5d71fbb36

+ 1 - 0
build.gradle

@@ -216,6 +216,7 @@ subprojects {
         implementation group: 'org.springframework.retry', name: 'spring-retry', version: "${springretryVersion}"
         testImplementation group: 'org.springframework', name: 'spring-test', version: "${springVersion}"
         //spring-security
+        implementation group: 'org.springframework.security', name: 'spring-security-config', version: "${springSecurityVersion}"
         implementation group: 'org.springframework.security', name: 'spring-security-core', version: "${springSecurityVersion}"
         implementation group: 'org.springframework.security', name: 'spring-security-web', version: "${springSecurityVersion}"
         implementation group: 'org.springframework.security', name: 'spring-security-crypto', version: "${springSecurityVersion}"

+ 6 - 8
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/dromara/maxkey/authz/endpoint/OnlineSessionEndpoint.java

@@ -20,27 +20,25 @@ package org.dromara.maxkey.authz.endpoint;
 import org.dromara.maxkey.authn.session.Session;
 import org.dromara.maxkey.authn.session.SessionManager;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
 
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 
 @Tag(name = "3-1-在线ticket文档模块")
-@Controller
+@RestController
 @RequestMapping(value={"/onlineticket"})
 public class OnlineSessionEndpoint {
 
     @Autowired
     protected SessionManager sessionManager;
     
-    @Operation(summary = "在线ticket验证接口", description = "",method="GET")
-    @ResponseBody
-    @RequestMapping(value="/validate") 
-    public String ticketValidate(
-            @RequestParam(value ="ticket",required = true) String ticket) {
+    @Operation(summary = "在线ticket验证接口", description = "")
+    @GetMapping(value="/validate") 
+    public String ticketValidate(@RequestParam(value ="ticket",required = true) String ticket) {
         Session session = sessionManager.get(ticket);
         return session == null ? "" : session.getId();
     }

+ 6 - 0
maxkey-starter/maxkey-starter-captcha/src/main/java/org/dromara/maxkey/web/contorller/ImageCaptchaEndpoint.java

@@ -18,6 +18,10 @@
 package org.dromara.maxkey.web.contorller;
 
 import com.google.code.kaptcha.Producer;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
 import java.awt.image.BufferedImage;
 import org.apache.commons.lang3.StringUtils;
 import org.dromara.maxkey.authn.jwt.AuthTokenService;
@@ -38,6 +42,7 @@ import org.springframework.web.bind.annotation.RestController;
  * @author Crystal.Sea
  *
  */
+@Tag(name = "验证码模块")
 @RestController
 public class ImageCaptchaEndpoint {
     private static final Logger _logger = LoggerFactory.getLogger(ImageCaptchaEndpoint.class);
@@ -57,6 +62,7 @@ public class ImageCaptchaEndpoint {
      * @param request HttpServletRequest
      * @param response HttpServletResponse
      */
+    @Operation(summary = "图片验证码接口", description = "图片验证码接口",method="GET")
     @GetMapping(value={"/captcha"}, produces = {MediaType.APPLICATION_JSON_VALUE})
     public  Message<ImageCaptcha> captchaHandleRequest( 
                 @RequestParam(value="captcha",required=false,defaultValue="text") String captchaType,

+ 89 - 0
maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/MvcSecurityAutoConfiguration.java

@@ -0,0 +1,89 @@
+/*
+ * Copyright [2025] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+ 
+package org.dromara.maxkey.autoconfigure;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.factory.PasswordEncoderFactories;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
+
+/**
+ * protected urls
+ */
+@AutoConfiguration
+@EnableWebSecurity
+public class MvcSecurityAutoConfiguration {
+    private static final Logger logger = LoggerFactory.getLogger(MvcSecurityAutoConfiguration.class);
+    
+    static final String [] protectedUrls = {"/actuator","/actuator/**","/swagger-ui","/swagger-ui/**"};
+    
+    @Value("${spring.security.enabled:true}")
+    boolean securityEnabled;
+    
+    @Value("${spring.security.user.name:maxkey}")
+    String username;
+    
+    @Value("${spring.security.user.password:password}")
+    String password;
+    
+    @Bean
+    SecurityFilterChain securityFilterChain(HttpSecurity http,@Qualifier("securityProviderManager")ProviderManager securityProviderManager) throws Exception {
+        if(this.securityEnabled) {
+            http.securityMatcher(protectedUrls)
+                 .authenticationManager(securityProviderManager)
+                 .authorizeHttpRequests(auth -> auth
+                         .requestMatchers(protectedUrls).authenticated()
+                         )
+                 .httpBasic(Customizer.withDefaults());
+        }else {
+            http.authorizeHttpRequests(auth -> auth
+                    .requestMatchers(protectedUrls).permitAll()
+                );
+        }
+        logger.debug("init securityFilterChain");
+        return http.build();
+    }
+    
+    @Bean(name="securityUserDetailsService")                                                              
+    UserDetailsService securityUserDetailsService() {
+        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
+        InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
+        userDetailsService.createUser(User.withUsername(this.username).password(encoder.encode(this.password)).roles("ACTUATOR", "MONITOR").build());
+        return userDetailsService;
+    }
+    
+    @Bean(name="securityProviderManager")                                                              
+    ProviderManager securityProviderManager(@Qualifier("securityUserDetailsService") UserDetailsService securityUserDetailsService) {
+        DaoAuthenticationProvider daoAuthenticationProvider= new DaoAuthenticationProvider(securityUserDetailsService);
+        return new ProviderManager(daoAuthenticationProvider);
+    }
+    
+}

+ 16 - 5
maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/SwaggerAutoConfiguration.java

@@ -20,6 +20,8 @@ import io.swagger.v3.oas.models.info.License;
 public class SwaggerAutoConfiguration {
     static final  Logger _logger = LoggerFactory.getLogger(SwaggerAutoConfiguration.class);
     
+    static final String OFFICIAL_WEBSITE = "https://www.maxkey.top/";
+    
     @Value("${maxkey.swagger.title}")
     String title;
     
@@ -29,7 +31,7 @@ public class SwaggerAutoConfiguration {
     @Value("${maxkey.swagger.version}")
     String version;
     
-    @Value("${maxkey.swagger.enable}")
+    @Value("${springdoc.swagger-ui.enabled}")
     boolean enable;
 
     @Bean
@@ -66,20 +68,26 @@ public class SwaggerAutoConfiguration {
                 
             };
         String[] packagedToMatch = { "org.dromara.maxkey.authz" };
-        return GroupedOpenApi.builder().group(title)
+        _logger.debug("OpenApi enable {}",enable);
+        if(enable) {
+        	return GroupedOpenApi.builder().group(title)
                 .pathsToMatch(paths)
                 .packagesToScan(packagedToMatch).build();
+        }else {
+        	return null;
+        }
     }
 
     @Bean
     OpenAPI docOpenAPI() {
-        return new OpenAPI()
+        if(enable) {
+        	return new OpenAPI()
                 .info(
                     new Info()
                         .title(title)
                         .description(description)
                         .version(version)
-                        .termsOfService("https://www.maxkey.top/")
+                        .termsOfService(OFFICIAL_WEBSITE)
                         .license(
                             new License()
                                 .name("Apache License, Version 2.0")
@@ -89,7 +97,10 @@ public class SwaggerAutoConfiguration {
                 externalDocs(
                         new ExternalDocumentation()
                         .description("MaxKey.top contact support@maxsso.net")
-                        .url("https://www.maxkey.top/")
+                        .url(OFFICIAL_WEBSITE)
                 );
+        }else {
+        	return null;
+        }
     }
 }

+ 2 - 1
maxkey-starter/maxkey-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -1,5 +1,6 @@
 org.dromara.maxkey.autoconfigure.ApplicationAutoConfiguration
 org.dromara.maxkey.autoconfigure.MvcAutoConfiguration
 org.dromara.maxkey.autoconfigure.MvcResourceAutoConfiguration
+org.dromara.maxkey.autoconfigure.MvcSecurityAutoConfiguration
 org.dromara.maxkey.autoconfigure.RedisAutoConfiguration
-org.dromara.maxkey.autoconfigure.SwaggerAutoConfiguration
+org.dromara.maxkey.autoconfigure.SwaggerAutoConfiguration

+ 3 - 4
maxkey-webs/maxkey-web-maxkey/src/main/resources/application-maxkey.properties

@@ -289,7 +289,6 @@ spring.boot.admin.client.password               =${SPRING_BOOT_ADMIN_PASSWORD:}
 #springfox.documentation.swagger.v2.path=/api-docs                         #
 #Swagger Configure Properties                                              #
 ############################################################################
-maxkey.swagger.enable                           =true
 maxkey.swagger.title                            =MaxKey\u5355\u70b9\u767b\u5f55\u8ba4\u8bc1\u7cfb\u7edfAPI\u6587\u6863
 maxkey.swagger.description                      =MaxKey\u5355\u70b9\u767b\u5f55\u8ba4\u8bc1\u7cfb\u7edfAPI\u6587\u6863
 maxkey.swagger.version                          =${application.formatted-version}
@@ -300,9 +299,9 @@ springdoc.swagger-ui.tags-sorter                =alpha
 springdoc.swagger-ui.operations-sorter          =alpha
 springdoc.swagger-ui.showExtensions             =true
 springdoc.api-docs.path                         =/v3/api-docs
-springdoc.group-configs[0].group                =default
-springdoc.group-configs[0].paths-to-match       =/*
-springdoc.group-configs[0].packages-to-scan     =org.dromara.maxkey
+#springdoc.group-configs[0].group                =default
+#springdoc.group-configs[0].paths-to-match       =/*
+#springdoc.group-configs[0].packages-to-scan     =org.dromara.maxkey
 
 knife4j.enable                                  =true
 knife4j.setting.language                        =ZH_CN

+ 3 - 4
maxkey-webs/maxkey-web-mgt/src/main/resources/application-maxkey-mgt.properties

@@ -217,7 +217,6 @@ spring.boot.admin.client.password               =${SPRING_BOOT_ADMIN_PASSWORD:}
 #springfox.documentation.swagger.v2.path=/api-docs                         #
 #Swagger Configure Properties                                              #
 ############################################################################
-maxkey.swagger.enable                           =true
 maxkey.swagger.title                            =MaxKey\u5355\u70b9\u767b\u5f55\u8ba4\u8bc1\u7cfb\u7edfAPI\u6587\u6863
 maxkey.swagger.description                      =MaxKey\u5355\u70b9\u767b\u5f55\u8ba4\u8bc1\u7cfb\u7edfAPI\u6587\u6863
 maxkey.swagger.version                          =${application.formatted-version}
@@ -228,9 +227,9 @@ springdoc.swagger-ui.tags-sorter                =alpha
 springdoc.swagger-ui.operations-sorter          =alpha
 springdoc.swagger-ui.showExtensions             =true
 springdoc.api-docs.path                         =/v3/api-docs
-springdoc.group-configs[0].group                =default
-springdoc.group-configs[0].paths-to-match       =/*
-springdoc.group-configs[0].packages-to-scan     =org.dromara.maxkey
+#springdoc.group-configs[0].group                =default
+#springdoc.group-configs[0].paths-to-match       =/*
+#springdoc.group-configs[0].packages-to-scan     =org.dromara.maxkey
 
 knife4j.enable                                  =true
 knife4j.setting.language                        =ZH_CN

+ 3 - 4
maxkey-webs/maxkey-web-openapi/src/main/resources/application-maxkey-openapi.properties

@@ -215,7 +215,6 @@ spring.boot.admin.client.password               =${SPRING_BOOT_ADMIN_PASSWORD:}
 #springfox.documentation.swagger.v2.path=/api-docs                         #
 #Swagger Configure Properties                                              #
 ############################################################################
-maxkey.swagger.enable                           =true
 maxkey.swagger.title                            =MaxKey\u5355\u70b9\u767b\u5f55\u8ba4\u8bc1\u7cfb\u7edfAPI\u6587\u6863
 maxkey.swagger.description                      =MaxKey\u5355\u70b9\u767b\u5f55\u8ba4\u8bc1\u7cfb\u7edfAPI\u6587\u6863
 maxkey.swagger.version                          =${application.formatted-version}
@@ -226,9 +225,9 @@ springdoc.swagger-ui.tags-sorter                =alpha
 springdoc.swagger-ui.operations-sorter          =alpha
 springdoc.swagger-ui.showExtensions             =true
 springdoc.api-docs.path                         =/v3/api-docs
-springdoc.group-configs[0].group                =default
-springdoc.group-configs[0].paths-to-match       =/*
-springdoc.group-configs[0].packages-to-scan     =org.dromara.maxkey
+#springdoc.group-configs[0].group                =default
+#springdoc.group-configs[0].paths-to-match       =/*
+#springdoc.group-configs[0].packages-to-scan     =org.dromara.maxkey
 
 knife4j.enable                                  =true
 knife4j.setting.language                        =ZH_CN