Basic Auth Security in Spring Boot 2

Upasana | December 30, 2019 | 3 min read | 2,104 views | Spring Boot 2


We will create a simple Spring Boot 2.2 powered REST API and secure it using Basic Authentication mechanism. We will be using Kotlin language for implementing this tutorial.

Download the source code

You can download the entire source of this project from github:
https://github.com/cancerian0684/tutorial-basic-auth-server

Perquisites

  1. Java 8/11 and Kotlin

  2. IDE like IntelliJ IDEA or Eclipse

  3. Gradle 6

  4. Spring Boot 2.2.2

  5. curl or POSTMAN for testing REST API

Using Spring Initializer for project template

You can head over to Spring Initializer at https://start.spring.io/ and create a project template with below configuration.

spring initializer basic auth
Spring initializer for project template

Import project into favorite IDE

You can import the project structure created in above step into IntelliJ IDEA and start implementing the rest of important stuff.

Build file contains the required dependencies: Kotlin, spring-boot-starter-web and spring-boot-starter-security.

/build.gradle
buildscript {
	ext.kotlin_version = '1.3.61'
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
		classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlin_version}")
		classpath("org.jetbrains.kotlin:kotlin-noarg:${kotlin_version}")
	}
}

... rest of the stuff

dependencies {
	compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
	compile('com.fasterxml.jackson.module:jackson-module-kotlin')
	compile('org.jetbrains.kotlin:kotlin-reflect')

	compile 'org.springframework.boot:spring-boot-starter-security'
	compile 'org.springframework.boot:spring-boot-starter-web'
}

App entry point

We need to create an app entry point that we can run to start the application.

BasicAuthApp.java
@SpringBootApplication
public class BasicAuthApp {

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

}

Create REST endpoint

Lets create a REST endpoint using Spring MVC.

HelloController.kt
@RestController
class HelloController {

    @GetMapping("/api/health")
    fun hello(): Health {
        return Health.UP
    }

}

data class Health(val status: String) {
    companion object {
        val UP = Health("UP")
    }
}

This endpoint simply returns hardcoded health indicators.

Securing the endpoint using Spring Security

Configuring Basic Authentication is quite straight forward and easy using Spring Boot. All we need to do is to extend WebSecurityConfigurerAdapter as shown below.

WebSecurityConfiguration.kt
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
class WebSecurityConfig : WebSecurityConfigurerAdapter() {

    override fun configure(http: HttpSecurity) {
        http
                .csrf().disable()
                .authorizeRequests()
                .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                .antMatchers(HttpMethod.POST, "/login", "/register").permitAll()
                .antMatchers("/api/**").authenticated()     (1)
                .anyRequest().authenticated()
                .and()
                .httpBasic()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    }

    @Autowired
    fun configureGlobal(auth: AuthenticationManagerBuilder) {
        auth.inMemoryAuthentication()   (2)
                .withUser("admin")
                .password("{noop}password")
                .roles("ADMIN")
    }
}
1 We configure Spring Security to protect /api/** endpoint so that only authenticated requests are allowed.
2 We are creating in memory user pool with given plain text credentials and authorities.

Start the server

We can start the server using gradle command line:

Starting the server
$ ./gradlew bootRun

this command will start the server at default port 8080.

Test the endpoint

We can use curl to test the API endpoints.

Curl request without credentials
$ curl -i -X GET http://localhost:8080/api/health
Response
HTTP/1.1 401
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 07 Apr 2019 14:50:20 GMT
Response body
{
    "timestamp": "2019-04-07T14:51:55.207+0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "No message available",
    "path": "/api/hello"
}

We can see that server returns 401 response code when we hit it without passing the basic auth credentials.

Now lets pass on the credentials and try it again:

Request with Basic Auth
$ curl -i --user user1:password -X GET http://localhost:8080/api/health
Response
{"status":"UP"}

we can see that API endpoint returns the health when we provide user credentials using basic auth.

We can also using POSTMAN to hit and endpoint by providing credentials in Basic Auth format.

postmain basic auth
Using POSTMAN to hit the endpoint

and it works!


Top articles in this category:
  1. Spring RestTemplate Basic Authentication
  2. Spring Boot WebClient Basic Authentication
  3. What is new in Spring Boot 2
  4. Spring Data ElasticSearch with Basic Auth
  5. Redis rate limiter in Spring Boot
  6. Feign RequestInterceptor in Spring Boot
  7. Setting a Random Port in Spring Boot Application at startup

Recommended books for interview preparation:

Find more on this topic: