diff --git a/build.gradle b/build.gradle index e70cf4900..f226a94be 100644 --- a/build.gradle +++ b/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}" diff --git a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/dromara/maxkey/authz/endpoint/OnlineSessionEndpoint.java b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/dromara/maxkey/authz/endpoint/OnlineSessionEndpoint.java index 39b2d5e56..a25b183e4 100644 --- a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/dromara/maxkey/authz/endpoint/OnlineSessionEndpoint.java +++ b/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(); } diff --git a/maxkey-starter/maxkey-starter-captcha/src/main/java/org/dromara/maxkey/web/contorller/ImageCaptchaEndpoint.java b/maxkey-starter/maxkey-starter-captcha/src/main/java/org/dromara/maxkey/web/contorller/ImageCaptchaEndpoint.java index dea382f5d..5eb1f8016 100644 --- a/maxkey-starter/maxkey-starter-captcha/src/main/java/org/dromara/maxkey/web/contorller/ImageCaptchaEndpoint.java +++ b/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 captchaHandleRequest( @RequestParam(value="captcha",required=false,defaultValue="text") String captchaType, diff --git a/maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/MvcSecurityAutoConfiguration.java b/maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/MvcSecurityAutoConfiguration.java new file mode 100644 index 000000000..c97f62774 --- /dev/null +++ b/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); + } + +} diff --git a/maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/SwaggerAutoConfiguration.java b/maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/SwaggerAutoConfiguration.java index 87fddea7e..653c87ff6 100644 --- a/maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/SwaggerAutoConfiguration.java +++ b/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; + } } } diff --git a/maxkey-starter/maxkey-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/maxkey-starter/maxkey-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index de0022d00..c1a85013c 100644 --- a/maxkey-starter/maxkey-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/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 \ No newline at end of file +org.dromara.maxkey.autoconfigure.SwaggerAutoConfiguration diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/resources/application-maxkey.properties b/maxkey-webs/maxkey-web-maxkey/src/main/resources/application-maxkey.properties index 0bff4bf8d..7f93a59af 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/resources/application-maxkey.properties +++ b/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 diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/application-maxkey-mgt.properties b/maxkey-webs/maxkey-web-mgt/src/main/resources/application-maxkey-mgt.properties index 7aee4fd99..6ec1f6105 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/application-maxkey-mgt.properties +++ b/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 diff --git a/maxkey-webs/maxkey-web-openapi/src/main/resources/application-maxkey-openapi.properties b/maxkey-webs/maxkey-web-openapi/src/main/resources/application-maxkey-openapi.properties index ff99b0b49..2ba3db11b 100644 --- a/maxkey-webs/maxkey-web-openapi/src/main/resources/application-maxkey-openapi.properties +++ b/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