Springboot REST-API Basic Auth with Google Secret Manager

Paras Bansal
3 min readAug 27, 2021

--

Springboot apps provide readily available security framework which can be implemented in many ways. Here I am implementing the in-memory basic authentication. So basic authentication is not so secure, but the password here can be secured and stored in Google Secret manager and the apps using the REST API need to obtain the password directly from Secret Manager which can easily be controlled by service accounts.

To start with code, here are the dependencies I am using:

dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'com.google.cloud:spring-cloud-gcp-starter-secretmanager'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

It’s a straightforward api implementation, where the password is obtained from Google Secret Manager using a config setting as:

spring:
application:
name: spring-basic-auth
server:
port: 8080
api_password: ${sm://api-password/latest}

Remember to have bootstrap.yaml in the config directory:

spring:
cloud:
gcp:
secretmanager: enabled

Before you run the app, remember to have below environment variable, where serviceaccount.json is the JSON file downloaded when you create the service account which has required permissions for Google Secret Manager:

GOOGLE_APPLICATION_CREDENTIALS=serviceaccount.json

This will ensure that app authenticates itself during the boot with the service account and refresh the password value from the GCP Secret Manager directly.

This is very important step even while deploying the docker container as the container should have the service account mounted which has access to GCP and corresponding secret.

Next we go to WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${spring.api_password}")
private String api_password;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(new BCryptPasswordEncoder())
.withUser("apiuser")
.password(getEncodedPassword(api_password))
.roles("USER")
;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().authenticated();
}
private String getEncodedPassword(String pwd) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder.encode(pwd);
}
}

First method here creates the in-memory user with a password refreshed from Google Secret Manager

Second method implements the auth mechanism using httpBasic. CSRF is disabled here for REST implementation.

So, all in all very straightforward, right :)

Here are the results, with correct password:

With wrong password, you get 401 Unauthorized:

That’s it for this story. Feel free to leave your comments. Code can found on Github: https://github.com/paras301/spring-boot-basic-authentication

Thank you!

--

--

Paras Bansal
Paras Bansal

Written by Paras Bansal

Senior Architect, Engineer by heart

No responses yet