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
-
Java 8/11 and Kotlin
-
IDE like IntelliJ IDEA or Eclipse
-
Gradle 6
-
Spring Boot 2.2.2
-
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.
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
.
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.
@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.
@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.
@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:
$ ./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 -i -X GET http://localhost:8080/api/health
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
{
"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:
$ curl -i --user user1:password -X GET http://localhost:8080/api/health
{"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.
and it works!
Top articles in this category:
- Spring RestTemplate Basic Authentication
- Spring Boot WebClient Basic Authentication
- What is new in Spring Boot 2
- Spring Data ElasticSearch with Basic Auth
- Redis rate limiter in Spring Boot
- Feign RequestInterceptor in Spring Boot
- Setting a Random Port in Spring Boot Application at startup