본문 바로가기
개발/Web

[Spring] Spring Boot Admin 사용하기 - Log, Login 적용

by zuzuu 2022. 1. 25.
반응형

 

1. 기본 세팅

1.1 Admin Server

  • maven 혹은 gradle에 spring-boot-admin-starter-server 라이브러리 추가
<!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-server -->
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-server</artifactId>
    <version>2.6.2</version>
</dependency>

 

// https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-server
implementation 'de.codecentric:spring-boot-admin-starter-server:2.6.2'

 

  • @EnableAdminServer 추가
@SpringBootApplication
@EnableAdminServer
public class AdminApplication {

	public static void main(String[] args) {
		SpringApplication.run(AdminApplication.class, args);
	}

}

 

1.2 Client

  • maven 혹은 gradle에 spring-boot-admin-starter-client 라이브러리 추가
<!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-client -->
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.6.2</version>
</dependency>

 

// https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-client
implementation 'de.codecentric:spring-boot-admin-starter-client:2.6.2'

 

  • application.yml 혹은 application.properties에 설정 추가
spring:
  boot:
    admin:
      client:
        url: http://localhost:58080 #admin server url
        instance:
          name: Client Server #admin UI 에서 보여질 이름 설정

 

주의사항

WAR, 즉 외부 Tomcat을 사용하는 경우엔 'spring.boot.admin.client.instance.service-base-url'를 추가해주어야 한다. 추가하지 않으면 아래와 같은 에러 발생..!  'spring.boot.admin.client.instance.service-url'로 설정해도 무방함!

java.lang.IllegalStateException: couldn't determine local port. Please set spring.boot.admin.client.instance.service-base-url.
        at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getLocalServerPort(DefaultApplicationFactory.java:192)
        at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getServiceBaseUrl(DefaultApplicationFactory.java:104)
        at de.codecentric.boot.admin.client.registration.ServletApplicationFactory.getServiceUrl(ServletApplicationFactory.java:63)
        at de.codecentric.boot.admin.client.registration.ServletApplicationFactory.getManagementBaseUrl(ServletApplicationFactory.java:76)
        at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getHealthUrl(DefaultApplicationFactory.java:154)
        at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.createApplication(DefaultApplicationFactory.java:80)
        at de.codecentric.boot.admin.client.registration.DefaultApplicationRegistrator.register(DefaultApplicationRegistrator.java:56)
        at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

 

여기까지 설정을 마치고 Admin Server와 Client Server를 구동시키고 Admin Server에 접속하면 아래와 같은 화면을 볼 수 있다.

 

 Spring Boot 2부터는 이렇게 기본세팅만 하게 되면 health 및 info이외의 endPoint가 노출되지 않는다고 한다. 


 

2. endPoints 노출 시키기

2.1 Client

  • application.yml 혹은 application.properties에 설정 추가
management:
  endpoints:
    web:
      exposure:
        include: "*" #노출시킬 endpoint, *는 전체 노출
  endpoint:
    health:
      show-details: always

include의 아스테리카(*)양 옆에 큰따옴표(")를 꼭 넣어주어야 한다! application.properties로는 설정을 안해봤는데 이건 그냥 아스테리카만 적어도 되는듯하다.

management.endpoint.health.show-details 속성의 기본값은 never 이므로 항상 상세 내역을 보고싶으면 always로 설정하면 된다.

 

모든 endPoints가 노출되도록 설정했기 때문에 다시 admin server에 접속해보면 아래와 같이 서버의 자세한 정보가 표시되는 것을 확인할 수 있다.

 


 

3. Admin Server에서 Client Server의 로그 확인하기

3.1 Client

  • application.yml 혹은 application.properties에 설정 추가
logging:
  config: classpath:logback-spring.xml
  file:
    name: D:\logs\logback.log

client server에서 생성되는 log파일의 경로를 지정해주면 된다. pattern으로도 할 수 있다는데 나는 일단 이렇게 세팅해서 확인했다.그럼 admin server의 왼쪽 목록에 '로그>로그파일' 이라는 탭이 생기고, client server의 로그를 실시간으로 확인할 수 있다.

 


 

4. Login 추가

Spring Boot Admin을 통해서 프로세스의 상태 정보를 조회하고, 설정 정보도 변경할 수 있다.
따라서 허용하지 않은 사용자가 이러한 행위를 할 수 없도록 Spring Boot Security를 적용하여 로그인이 가능하도록 하였다.

4.1 Admin Server

  • maven 혹은 gradle에 spring-boot-admin-starter-server 라이브러리 추가
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.6.2</version>
</dependency>

 

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security
implementation 'org.springframework.boot:spring-boot-starter-security:2.6.2'

 

  • application.yml 혹은 application.properties에 설정 추가
server.port=58080
spring.security.user.name=admin
spring.security.user.password=admin

 

  • SecuritySecureConfig.java  추가
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final AdminServerProperties adminServer;

    public SecurityConfig(AdminServerProperties adminServer) {
        this.adminServer = adminServer;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(this.adminServer.path("/"));

        http.authorizeRequests()
                // 모든 로그인 페이지에 대한 권한을 부여한다.
                .antMatchers(this.adminServer.path("/assets/**")).permitAll()
                .antMatchers(this.adminServer.path("/login")).permitAll()
                // 권한이 부여되지 않으면 인증을 요청 한다.
                .anyRequest().authenticated()
                .and()
                // 로그인 및 로그 아웃을 구성한다.
                .formLogin().loginPage(this.adminServer.path("/login")).successHandler(successHandler).and()
                .logout().logoutUrl(this.adminServer.path("/logout")).and()
                // Spring Boot Admin 클라이언트를 등록하기 위해 HTTP-Basic 지원을 사용한다.
                .httpBasic().and()
                .csrf()
                // 쿠키를 사용하여 CSRF 보호 기능 구현
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .ignoringAntMatchers(
                        // CRSF를 비활성화한다.
                        this.adminServer.path("/instances"),
                        // actuator EndPoint 대한 CRSF 보호를 비활성화한다.
                        this.adminServer.path("/actuator/**")
                );

    }
}

 

4.2 Client

  • application.yml 혹은 application.properties에 설정 추가

: 4.1(Admin Server의 설정파일)에서 설정한 username/password 정보와 같아야 한다.

spring:
  boot:
    admin:
      client:
        url: http://localhost:58080 #admin server url
        username: admin
        password: admin
        instance:
          name: Client Server

 

여기까지 설정하고 admin server에 접속하면 기존과 다르게 로그인화면이 먼저 보일 것이다. 설정한 ID/PW대로 입력하면 로그인이 가능하다.

 

 

 

 


 

로컬에선 잘 되다가 서버에 올리니 SSLHandshakeException 에러가 발생했다. 에러 내용은 SSL인증서의 DNS name과 실제 domain이 다르다는 것이다. (서버에 올린 client server는 ssl인증서가 적용된 https)

org.springframework.web.reactive.function.client.WebClientRequestException

No subject alternative DNS name matching ora19c found.; nested exception is javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching ora19c found.d.

Admin Server UI에선 실제 client 서버의 도메인이 아닌 ip 혹은 장비명으로 보여지고 있었다. 

이런 경우엔 Client Server 설정에 'spring.boot.admin.client.instance.service-url'을 추가해주어야 한다.

ex) spring.boot.admin.client.instance.service-url = https://<client-domain>:<port>/

 

 

 

728x90
반응형

댓글