Integrating SpringBootAdmin and Nacos and SpringSecurity

Keywords: Spring Java Maven

Preface

It is agreed as follows:

  • SpringBootAdmin - SBA
  • SpringSecurity - SSE

According to the current situation of search engine retrieval, everyone's application of SBA is relatively limited, with few divergent use. It is basically based on the example given on the official website (eureka-SBA-SSE), In addition, there are some confusing problems in various articles on the Internet, for example, when introducing dependency, spring cloud Alibaba has two groupids, For this reason, I was also confused. Based on the latest version and the recommended way of spring cloud Alibaba, I integrated SBA-SSE-Nacos and wrote this article. I hope that the people I see later will avoid running this hole again
Ps. it has to be said that the versions of microservices are really confusing.

start

Install Nacos

For specific installation tutorials, please refer to the official website. There is no need to elaborate here. The installation is very simple. Version: 1.4 + (in fact, all above 1.1 should be OK)

Create project

One maven project is enough. According to the general tutorial, two projects will be created, one as the Admin Server and one as the Admin Client, In order to reduce your learning cost, this example will directly register the project as AdminServer and configure it to be registered as a client to AdminServer

Introducing dependency

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.1.6</spring-boot-admin.version>
    </properties>
	
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-dependencies</artifactId>
                <version>${spring-boot-admin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
	
    <dependencies>
        <!--Security module-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Admin Server-->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <!--nacos Configure central client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>0.9.0.RELEASE</version>
        </dependency>
        <!--nacos Registry client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.9.0.RELEASE</version>
        </dependency>
        <!--Act as AdminServer Dependencies that must be introduced when clients of start-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator-autoconfigure</artifactId>
        </dependency>
        <!--Used for opening JMX operation-->
        <dependency>
            <groupId>org.jolokia</groupId>
            <artifactId>jolokia-core</artifactId>
        </dependency>
        <!--Act as AdminServer Dependencies that must be introduced when clients of end-->
		
    </dependencies>

To configure

Create AdminServerApp class

So much code, don't panic, just throw all the contents in it, no need to change

/**
 * @author vate
 * @date 2019/12/18 23:03
 */
@SpringBootApplication
@EnableAdminServer // Start as AdminServer
@EnableDiscoveryClient // Turn on service discovery
public class AdminServerApp {
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(AdminServerApp.class);
        springApplication.run(args);
    }

    @Profile("dev")
    @Configuration()
    public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter {

        private final String adminContextPath;

        public SecurityPermitAllConfig(AdminServerProperties adminServerProperties) {
            this.adminContextPath = adminServerProperties.getContextPath();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().permitAll().and().csrf()
                    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).ignoringRequestMatchers(
                    new AntPathRequestMatcher(this.adminContextPath + "/instances", HttpMethod.POST.toString()),
                    new AntPathRequestMatcher(this.adminContextPath + "/instances/*",
                            HttpMethod.DELETE.toString()),
                    new AntPathRequestMatcher(this.adminContextPath + "/actuator/**"));
        }
    }

    @Profile("pro")
    @Configuration()
    public static class SecuritySecureConfig extends WebSecurityConfigurerAdapter {

        private final String adminContextPath;

        public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
            this.adminContextPath = adminServerProperties.getContextPath();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
            successHandler.setTargetUrlParameter("redirectTo");
            successHandler.setDefaultTargetUrl(this.adminContextPath + "/");

            http.authorizeRequests()
                    .antMatchers(this.adminContextPath + "/assets/**").permitAll()
                    .antMatchers(this.adminContextPath + "/login").permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin().loginPage(this.adminContextPath + "/login").successHandler(successHandler).and()
                    .logout().logoutUrl(this.adminContextPath + "/logout").and()
                    .httpBasic().and()
                    .csrf()
                    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                    .ignoringRequestMatchers(
                            new AntPathRequestMatcher(this.adminContextPath + "/instances", HttpMethod.POST.toString()),
                            new AntPathRequestMatcher(this.adminContextPath + "/instances/*", HttpMethod.DELETE.toString()),
                            new AntPathRequestMatcher(this.adminContextPath + "/actuator/**")
                    );
            // @formatter:on
        }

    }

}

Create bootstrap.yaml file

Fill in the following to configure the nacos Service Center

spring:
  application:
    name: admin-server
  cloud:
    # nacos configuration
    nacos:
      discovery:
        server-addr: xxx:8848

Create application.yaml file

spring:
  profiles:
    active: pro,admin
server:
  port: 3333
---
spring:
  profiles: dev
---
spring:
  profiles: pro
  security:
    user:
      name: "user"
      password: "password"
  cloud:
    nacos:
      discovery:
        # When the service instance is registered in the service center, the user name and password used to access the service are carried in the meta information
        metadata:
          user.name: "user"         
          user.password: "password" 
# If you use eureka as the registry, you will use this configuration
eureka:
  instance:
    # When the service instance is registered in the service center, the user name and password used to access the service are carried in the meta information
    metadata-map:
      user.name: "user"         #These two are needed so that the server
      user.password: "password"  #can access the protected client endpoints

In the above configuration file, whether as a Nacos client or Eureka client, we have a metadata configuration:

nacos:
metadata:
  user.name: "user"         
  user.password: "password" 
eureka:
metadata-map:
user.name: "user"         
user.password: "password" 

This configuration is extremely important, For projects with integrated Security, all our interfaces are protected. When I register this instance in the registry, However, the access account and password are not provided. How can the Admin Server access the interface of this instance to obtain the status information? Therefore, the meaning of this configuration is to upload the user name and password of the Security framework defined by this instance to the registration center as meta information, To enable the AdminServer to obtain the key to access each service while pulling the registration service list from the registration center, so that the monitoring function of the AdminServer can work.

Create the application-admin.yaml file

Fill in the following

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

I won't explain these configurations. Readers can go to the search engine to search the spring boot actuator configuration details later.

Startup application

To view the Nacos interface:

The default username / password of Nacos is: nacos/nacos

Sign in:

Home page:

Wallboard:

Click the box to see:

successfully.

Epilogue

You may have some doubts about the monitored client? Isn't AdminServer a server? What about the configuration of adminclient?

Answer: when we integrate the service discovery dependency starter of Nacos, the Nacos client will automatically register our service instance to the Nacos registry when the application starts.
And the principle of the integration of AdminServer and registry, In fact, the way that the original Client obtains the address of the AdminServer directly and registers itself into the AdminServer manually becomes that the AdminClient service registers in the registration center, The AdminServer can monitor all services by directly going to the registration center to dynamically obtain all registration services (provided that the client integrates the activator and correctly configures the meta information of relevant access).

I have to mention it again if AdminClient Integrated Security The user access information must be carried in the meta information:
nacos:
metadata:
  user.name: "user"         
  user.password: "password" 
eureka:
metadata-map:
user.name: "user"        
user.password: "password"

Posted by stevel on Wed, 18 Mar 2020 08:30:50 -0700