Commit 88f322311eb8c0e5267c6a37cde120cd843d51ff
1 parent
d860ca2c
feat:【infra】spring boot admin 默认需要登录
Showing
4 changed files
with
102 additions
and
7 deletions
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/monitor/config/AdminServerConfiguration.java
| 1 | package cn.iocoder.yudao.module.infra.framework.monitor.config; | 1 | package cn.iocoder.yudao.module.infra.framework.monitor.config; |
| 2 | 2 | ||
| 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer; | 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer; |
| 4 | +import jakarta.servlet.DispatcherType; | ||
| 5 | +import org.springframework.beans.factory.annotation.Value; | ||
| 6 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
| 7 | +import org.springframework.context.annotation.Bean; | ||
| 4 | import org.springframework.context.annotation.Configuration; | 8 | import org.springframework.context.annotation.Configuration; |
| 9 | +import org.springframework.core.annotation.Order; | ||
| 10 | +import org.springframework.security.config.Customizer; | ||
| 11 | +import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 12 | +import org.springframework.security.core.userdetails.User; | ||
| 13 | +import org.springframework.security.core.userdetails.UserDetails; | ||
| 14 | +import org.springframework.security.crypto.password.PasswordEncoder; | ||
| 15 | +import org.springframework.security.provisioning.InMemoryUserDetailsManager; | ||
| 16 | +import org.springframework.security.web.SecurityFilterChain; | ||
| 17 | +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; | ||
| 18 | +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; | ||
| 5 | 19 | ||
| 20 | +/** | ||
| 21 | + * Spring Boot Admin Server 配置 | ||
| 22 | + * | ||
| 23 | + * 包含 Admin Server 的启用配置和安全配置 | ||
| 24 | + * 安全配置独立于 {@link cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter}, | ||
| 25 | + * 使用 HTTP Basic 认证保护 Admin Server 端点,不影响现有的 Token 认证机制 | ||
| 26 | + * | ||
| 27 | + * @author 芋道源码 | ||
| 28 | + */ | ||
| 6 | @Configuration(proxyBeanMethods = false) | 29 | @Configuration(proxyBeanMethods = false) |
| 7 | @EnableAdminServer | 30 | @EnableAdminServer |
| 31 | +@ConditionalOnClass(name = "de.codecentric.boot.admin.server.config.AdminServerProperties") // 目的:按需启动 spring boot admin 监控服务 | ||
| 8 | public class AdminServerConfiguration { | 32 | public class AdminServerConfiguration { |
| 33 | + | ||
| 34 | + @Value("${spring.boot.admin.context-path:''}") | ||
| 35 | + private String adminSeverContextPath; | ||
| 36 | + | ||
| 37 | + @Value("${spring.boot.admin.client.username:admin}") | ||
| 38 | + private String username; | ||
| 39 | + | ||
| 40 | + @Value("${spring.boot.admin.client.password:admin}") | ||
| 41 | + private String password; | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * Spring Boot Admin 专用的 InMemoryUserDetailsManager | ||
| 45 | + * 使用内存存储,与系统用户隔离 | ||
| 46 | + */ | ||
| 47 | + @Bean("adminUserDetailsManager") | ||
| 48 | + public InMemoryUserDetailsManager adminUserDetailsManager(PasswordEncoder passwordEncoder) { | ||
| 49 | + UserDetails adminUser = User.builder() | ||
| 50 | + .username(username) | ||
| 51 | + .password(passwordEncoder.encode(password)) | ||
| 52 | + .roles("ADMIN_SERVER") | ||
| 53 | + .build(); | ||
| 54 | + return new InMemoryUserDetailsManager(adminUser); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * Spring Boot Admin Server 的 SecurityFilterChain | ||
| 59 | + * 使用 @Order(1) 确保优先于默认的 SecurityFilterChain 匹配 | ||
| 60 | + */ | ||
| 61 | + @Bean("adminServerSecurityFilterChain") | ||
| 62 | + @Order(1) | ||
| 63 | + public SecurityFilterChain adminServerSecurityFilterChain(HttpSecurity httpSecurity, | ||
| 64 | + InMemoryUserDetailsManager adminUserDetailsManager) throws Exception { | ||
| 65 | + // 登录成功后的处理器 | ||
| 66 | + SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); | ||
| 67 | + successHandler.setTargetUrlParameter("redirectTo"); | ||
| 68 | + successHandler.setDefaultTargetUrl(adminSeverContextPath + "/"); | ||
| 69 | + | ||
| 70 | + // 配置 HttpSecurity 对象 | ||
| 71 | + httpSecurity | ||
| 72 | + // 仅匹配 Admin Server 的路径 | ||
| 73 | + .securityMatcher(adminSeverContextPath + "/**") | ||
| 74 | + // 使用独立的 UserDetailsManager | ||
| 75 | + .userDetailsService(adminUserDetailsManager) | ||
| 76 | + // 授权配置 | ||
| 77 | + .authorizeHttpRequests(auth -> auth | ||
| 78 | + .requestMatchers(adminSeverContextPath + "/assets/**").permitAll() // 静态资源允许匿名访问 | ||
| 79 | + .requestMatchers(adminSeverContextPath + "/login").permitAll() // 登录页面允许匿名访问 | ||
| 80 | + .dispatcherTypeMatchers(DispatcherType.ASYNC).permitAll() // 异步请求允许 | ||
| 81 | + .anyRequest().authenticated() // 其他请求需要认证 | ||
| 82 | + ) | ||
| 83 | + // 表单登录配置(用于 Admin UI 访问) | ||
| 84 | + .formLogin(form -> form | ||
| 85 | + .loginPage(adminSeverContextPath + "/login") | ||
| 86 | + .successHandler(successHandler) | ||
| 87 | + .permitAll() | ||
| 88 | + ) | ||
| 89 | + // 登出配置 | ||
| 90 | + .logout(logout -> logout | ||
| 91 | + .logoutUrl(adminSeverContextPath + "/logout") | ||
| 92 | + .logoutSuccessUrl(adminSeverContextPath + "/login") | ||
| 93 | + ) | ||
| 94 | + // HTTP Basic 认证(用于 Admin Client 注册) | ||
| 95 | + .httpBasic(Customizer.withDefaults()) | ||
| 96 | + // CSRF 配置 | ||
| 97 | + .csrf(csrf -> csrf | ||
| 98 | + .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) | ||
| 99 | + .ignoringRequestMatchers( | ||
| 100 | + adminSeverContextPath + "/instances", // Admin Client 注册端点忽略 CSRF | ||
| 101 | + adminSeverContextPath + "/actuator/**" // Actuator 端点忽略 CSRF | ||
| 102 | + ) | ||
| 103 | + ); | ||
| 104 | + return httpSecurity.build(); | ||
| 105 | + } | ||
| 106 | + | ||
| 9 | } | 107 | } |
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java
| 1 | package cn.iocoder.yudao.module.infra.framework.security.config; | 1 | package cn.iocoder.yudao.module.infra.framework.security.config; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; | 3 | import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; |
| 4 | -import org.springframework.beans.factory.annotation.Value; | ||
| 5 | import org.springframework.context.annotation.Bean; | 4 | import org.springframework.context.annotation.Bean; |
| 6 | import org.springframework.context.annotation.Configuration; | 5 | import org.springframework.context.annotation.Configuration; |
| 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| @@ -13,9 +12,6 @@ import org.springframework.security.config.annotation.web.configurers.AuthorizeH | @@ -13,9 +12,6 @@ import org.springframework.security.config.annotation.web.configurers.AuthorizeH | ||
| 13 | @Configuration(proxyBeanMethods = false, value = "infraSecurityConfiguration") | 12 | @Configuration(proxyBeanMethods = false, value = "infraSecurityConfiguration") |
| 14 | public class SecurityConfiguration { | 13 | public class SecurityConfiguration { |
| 15 | 14 | ||
| 16 | - @Value("${spring.boot.admin.context-path:''}") | ||
| 17 | - private String adminSeverContextPath; | ||
| 18 | - | ||
| 19 | @Bean("infraAuthorizeRequestsCustomizer") | 15 | @Bean("infraAuthorizeRequestsCustomizer") |
| 20 | public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { | 16 | public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { |
| 21 | return new AuthorizeRequestsCustomizer() { | 17 | return new AuthorizeRequestsCustomizer() { |
| @@ -32,9 +28,6 @@ public class SecurityConfiguration { | @@ -32,9 +28,6 @@ public class SecurityConfiguration { | ||
| 32 | .requestMatchers("/actuator/**").permitAll(); | 28 | .requestMatchers("/actuator/**").permitAll(); |
| 33 | // Druid 监控 | 29 | // Druid 监控 |
| 34 | registry.requestMatchers("/druid/**").permitAll(); | 30 | registry.requestMatchers("/druid/**").permitAll(); |
| 35 | - // Spring Boot Admin Server 的安全配置 | ||
| 36 | - registry.requestMatchers(adminSeverContextPath).permitAll() | ||
| 37 | - .requestMatchers(adminSeverContextPath + "/**").permitAll(); | ||
| 38 | // 文件读取 | 31 | // 文件读取 |
| 39 | registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll(); | 32 | registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll(); |
| 40 | } | 33 | } |
yudao-server/src/main/resources/application-dev.yaml
| @@ -138,6 +138,8 @@ spring: | @@ -138,6 +138,8 @@ spring: | ||
| 138 | url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址 | 138 | url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址 |
| 139 | instance: | 139 | instance: |
| 140 | service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME] | 140 | service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME] |
| 141 | + username: admin | ||
| 142 | + password: admin | ||
| 141 | # Spring Boot Admin Server 服务端的相关配置 | 143 | # Spring Boot Admin Server 服务端的相关配置 |
| 142 | context-path: /admin # 配置 Spring | 144 | context-path: /admin # 配置 Spring |
| 143 | 145 |
yudao-server/src/main/resources/application-local.yaml
| @@ -158,6 +158,8 @@ spring: | @@ -158,6 +158,8 @@ spring: | ||
| 158 | url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址 | 158 | url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址 |
| 159 | instance: | 159 | instance: |
| 160 | service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME] | 160 | service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME] |
| 161 | + username: admin | ||
| 162 | + password: admin | ||
| 161 | # Spring Boot Admin Server 服务端的相关配置 | 163 | # Spring Boot Admin Server 服务端的相关配置 |
| 162 | context-path: /admin # 配置 Spring | 164 | context-path: /admin # 配置 Spring |
| 163 | 165 |