SpringBootAdmin搭建过程

作者: 有钱买辣条 | 来源:发表于2018-03-17 19:46 被阅读7632次

    随着微服务的流行,相比较以前一个大型应用程序搞定所有需求,我们现在更倾向于把大型应用程序切分成多个微服务。而SpringBoot是微服务的基础,一个一个的微服务构成了一个错综复杂的系统,spring-boot-starter-actuator 是SpringBoot下的一个包它提供了监控接口,例如:/health、/info等等,实际上除了之前提到的信息,还有其他信息业需要监控:当前处于活跃状态的会话数量、当前应用的并发数、服务资源、延迟以及其他度量信息,精简配置。而SpringBootAdmin正是基于这些接口开发了一套功能强大的监控系统。

    创建SpringBootAdmin的Server端

    1.加入以下依赖

    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-server</artifactId>
    </dependency>
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-server-ui</artifactId>
    </dependency>
    

    2.在application中加入注解如下

    @Configuration
    @EnableAutoConfiguration
    @EnableAdminServer
    public class SpringBootAdminApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringBootAdminApplication.class, args);
        }
    }
    

    创建SpringBootAdmin的Client端

    1.加入以下依赖

    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-starter-client</artifactId>
    </dependency>
    

    client中引入很多其他包,目前用到的是 jolokia(用来添加JMX功能) 和 actuator(SpringBoot提供的监控端点所依赖的包)。

    2.配置文件中添加

    spring.boot.admin.url: http://localhost:8080  //要注册的服务端
    management.security.enabled: false //SpringBoot 1.5以后的版本都默认开启端点保护
    

    SpringBootAdmin的Server端也可以注册在eureka这样的管理中心上,好处是可以监控所有注册在eureka上的服务,SpringBootAdmin客户端无需再配置服务端,注册到Eureka上后,SpringBootAdmin可以定时拉取服务注册列表,无需再为服务节点配置监控中心的地址。

    为监控系统添加权限保护

    为server端设置登陆页面和权限

    1.在server端中需要引入如下依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-server-ui</artifactId>
    </dependency>
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-server-ui-login</artifactId>
    </dependency>
    

    2.修改配置文件

    security.user.name=aa
    security.user.password=aa //登陆用户名密码
    security.basic.enabled=false //关掉security框架自带的登陆弹出框
    

    3.配置config类

    @Bean
        public HttpHeadersProvider httpHeadersProvider() {
            return new ServerAuthHttpHeaderProvider();
        }
    
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            //忽略css.jq.img等文件
            web.ignoring().antMatchers("/**.html", "/**.css", "/img/**", "/**.js", "/third-party/**");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll().defaultSuccessUrl("/")
                    .and()//Logout Form configuration
                    .logout()
                    .deleteCookies("remove")
                    .logoutSuccessUrl("/login.html").permitAll()
                    .and().authorizeRequests().antMatchers(HttpMethod.POST, "/apiapplications/").permitAll()
                    .antMatchers("/health").permitAll()
                    .anyRequest().authenticated()//
                    .and().csrf().ignoringAntMatchers("/api/**", "/**")
                    .csrfTokenRepository(csrfTokenRepository()).and()
                    .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
        }
    
        private Filter csrfHeaderFilter() {
            return new OncePerRequestFilter() {
                @Override
                protected void doFilterInternal(HttpServletRequest request,
                                                HttpServletResponse response, FilterChain filterChain)
                        throws ServletException, IOException {
                    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
                    if (csrf != null) {
                        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                        String token = csrf.getToken();
                        if (cookie == null || token != null && !token.equals(cookie.getValue())) {
                            cookie = new Cookie("XSRF-TOKEN", token);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                    filterChain.doFilter(request, response);
                }
            };
        }
    
        private CsrfTokenRepository csrfTokenRepository() {
            HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
            repository.setHeaderName("X-XSRF-TOKEN");
            return repository;
        }
    

    为client端设置端点保护

    1.加入如下依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    

    2.修改配置文件

    #可在线查看日志
    endpoints.logfile.enabled=true
    logging.file=fileDir
    #客户端开启停止服务端点
    endpoints.shutdown.enabled=true
    #保护客户端端点数据
    security.user.name=aa
    security.user.password=aa
    security.basic.path=/aa
    eureka.instance.metadata-map.user.name=${security.user.name}
    eureka.instance.metadata-map.user.password=${security.user.password}
    

    Eureka中的metadataMap是专门用来存放一些自定义的数据,当注册中心或者其他服务需要此服务的某些配置时可以在metadataMap里取。实际上,每个instance都有各自的metadataMap,map中存放着需要用到的属性。例如,上面配置中的eureka.instance.metadata-map.user.name,当这个服务成功注册到Eureka上,SpringBootAdmin就会取拿到这个instance,进而拿到metadataMap里的属性,然后放入请求头,向此服务发送请求,访问此服务的actuator开放的端点。

    需要注意的是如果项目中用到了Zuul这样设置可能还不完善。例如,某服务用swagger2测接口,但是访问swagger的页面被设置了权限,此时直接访问swagger的页面会提示输入用户名和密码,但是即使输入正确也还是进入不了页面。这是因为Zuul转发请求默认是会省略一些东西的

    为了避免Zuul请求路由到别的系统泄露一些重要信息,在请求头中默认没有这三个属性。而SpringSecurity是通过请求中的请求头Authentiction来取账号密码,所以每次提交账号密码验证的时候都获取不到,解决办法是修改zuul配置 zuul.sensitive-headers= 覆盖zuul的默认配置即可。

    相关文章

      网友评论

      • else05:请修正 spring boot admin 的路径 , 路径最后多加了一个括号“)”

      本文标题:SpringBootAdmin搭建过程

      本文链接:https://www.haomeiwen.com/subject/prgjqftx.html