tahasozgen
tahasozgen

Reputation: 491

Unable to Access Spring Boot Actuator Endpoints

I try to use actuator endpoints in spring boot. The application runs smoothly. My pom file is given below:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.3</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.luv2code.springboot</groupId>
    <artifactId>thymeleafdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>thymeleafdemo</name>
    <description>Ab Jove principium</description>
    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>

        <!-- umumi bağımlılıklar -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId> 
        </dependency>
        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>2.11.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>

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

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

        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Here is the content of the application.properties file:

spring.datasource.url=DATABASE_URL
spring.datasource.username=USERNAME
spring.datasource.password=PASSWORD
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect

# Spring Data JPA properties
spring.data.jpa.repository.packages=com.yok.springboot.thymeleafdemo.dao
spring.data.jpa.entity.packages-to-scan=com.yok.springboot.thymeleafdemo.entity
spring.jpa.hibernate.use-new-id-generator-mappings=false
spring.jpa.hibernate.ddl-auto=create

#
# JDBC properties
#
app.datasource.jdbc-url=DATABASE_URL
app.datasource.username=USERNAME
app.datasource.password=PASSWORD

#
# Hikari properties
spring.datasource.hikari.maximumPoolSize=10
spring.datasource.hikari.idleTimeout=2000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=20000
spring.datasource.hikari.connectionTimeout=30000

# Actuator properties 
  
# expose all endpoints:
management.endpoints.web.exposure.include=*  
management.endpoints.beans.enabled=true
management.endpoints.web.exposure.include=info,env
management.endpoint.env.enabled=true
management.endpoint.info.enabled=true 
management.endpoints.enabled-by-default=true

This is the start of my Spring Boot Application:

package com.yok.springboot.thymeleafdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ThymeleafdemoApplication {

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

Whenever I try to connect /health,/Info or /metrics endpoint by typing http://localhost:8080/health, the HTTP request transfers to http://localhost:8080/showMyLoginPage. I cannot reach endpoint. How can I solve this? Thanks in advance.

Edit -1 Mr. Fatih demands me to observe the result "http://localhost:8080/actuator" and this picture reveals: the picture

Here is the console output of the application:

https://drive.google.com/file/d/1zYP1qe-Ohbcan93ZO6rqjxX9LqlGiIIg/view?usp=sharing

Edit-2
The problem is partly solved. The actuators are available after the login of the application. But the problem is, after the login page, the homepage appears. All actuators are working, however, whenever I hit http://localhost:8080/actuator/health URL, {"status":"DOWN"} appears at the screen. Here is the console output taken during this operation:


reached urls:
http://localhost:8080/showMyLoginPage http://localhost:8080/students/list/page/1 http://localhost:8080/actuator/health http://localhost:8080/actuator/heapdump http://localhost:8080/actuator/env

console output: (exception has thrown)

java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required. at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:1029) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:109) ~[HikariCP-4.0.3.jar:na] at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:159) ~[spring-jdbc-5.3.22.jar:5.3.22] at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:117) ~[spring-jdbc-5.3.22.jar:5.3.22] at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) ~[spring-jdbc-5.3.22.jar:5.3.22] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:330) ~[spring-jdbc-5.3.22.jar:5.3.22] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.getProduct(DataSourceHealthIndicator.java:122) ~[spring-boot-actuator-2.7.3.jar:2.7.3] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doDataSourceHealthCheck(DataSourceHealthIndicator.java:105) ~[spring-boot-actuator-2.7.3.jar:2.7.3] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doHealthCheck(DataSourceHealthIndicator.java:100) ~[spring-boot-actuator-2.7.3.jar:2.7.3]

Edit-3
Mr Fatih pointed out some of the changes at the WebSecurityConfiguration. I have changed the code and I am getting this error:

java.lang.IllegalStateException: permitAll only works with either HttpSecurity.authorizeRequests() or HttpSecurity.authorizeHttpRequests(). Please define one or the other but not both.

Here is the change I've made:

/*
* import section have omitted for brevity
*/

@Configuration
@EnableWebSecurity
public class DemoSecurityConfig {

    /*
     * other codes have omitted for brevity
     */

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http.authorizeHttpRequests(
                (authz) -> authz.antMatchers("/actuator/**").permitAll().anyRequest().authenticated());

        http.authorizeRequests(
                configurer -> configurer.antMatchers("/**").hasRole("ADMIN").antMatchers("/**").hasRole("USER"))

                .formLogin(configurer -> configurer.loginPage("/showMyLoginPage")
                        .loginProcessingUrl("/authenticateTheUser").permitAll())

                .logout(configurer -> configurer.permitAll())

                .exceptionHandling(configurer -> configurer.accessDeniedPage("/access-denied"));

        return http.build();

    }

}

Here is the console output: https://drive.google.com/file/d/1CtjRBHXVRqirZ0Vt_3FEhx_N9oEwyfFZ/view

Upvotes: 0

Views: 3549

Answers (2)

fatih
fatih

Reputation: 1420

You are using the spring-security package for application security. So when you want to access your /actuator endpoints, you need to log in first. If you want to access your /actuator endpoints without logging in, you must configure a security configuration. With the following configuration, you can exclude all endpoints starting with /actuator from security.

@EnableWebSecurity
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/actuator/**").permitAll().anyRequest().authenticated();
    }
}

Since WebSecurityConfigurerAdapter has been deprecated, you can do this as well.

@Configuration
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
        .authorizeHttpRequests(autz -> autz
                .mvcMatchers("/actuator/**").permitAll()
                .anyRequest().authenticated()
        );
    return http.build();
    }
}

** is a wildcard definition and allows you to access this endpoint without logging in, regardless of what comes after the actuator part.

Upvotes: 1

Neos
Neos

Reputation: 126

Please Consider using a version for your dependency as far as i remember 1.9.5 RELEASE or 1.9.5 might help in this context , i had the same issue a year ago.

Upvotes: 0

Related Questions