Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Securing Spring Boot API with API key and secret

I would like to secure the Spring Boot API so it is accessible only for the clients that has valid API key and secret. However, there is no authentication (standard login with username and password) inside the program as all data is anonymous. All I'm trying to achieve is that all API requests can be used only for specific third party front-end.

I found a lot of articles about how to secure the Spring Boot API with user authentication. But I don't need user authentication. What I am thinking of is just provide my client with API key and secret so he has access to the endpoints.

Could you please suggest me how can I achieve this? Thank you!

like image 989
Vitalii Oleksiv Avatar asked Jan 25 '18 15:01

Vitalii Oleksiv


People also ask

How API key is secured?

API keys are generally not considered secure; they are typically accessible to clients, making it easy for someone to steal an API key. Once the key is stolen, it has no expiration, so it may be used indefinitely, unless the project owner revokes or regenerates the key.

Is API key in header secure?

API keys are supposed to be a secret that only the client and server know. But, as well as Basic authentication, API key-based authentication is not considered secure unless used together with other security mechanisms such as HTTPS/SSL.


1 Answers

Create a filter that grabs what ever header(s) you're using for authentication.

import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;  public class APIKeyAuthFilter extends AbstractPreAuthenticatedProcessingFilter {      private String principalRequestHeader;      public APIKeyAuthFilter(String principalRequestHeader) {         this.principalRequestHeader = principalRequestHeader;     }      @Override     protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {         return request.getHeader(principalRequestHeader);     }      @Override     protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {         return "N/A";     }  } 

Configure the filter in your Web Security config.

import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException;  @Configuration @EnableWebSecurity @Order(1) public class APISecurityConfig extends WebSecurityConfigurerAdapter {      @Value("${yourapp.http.auth-token-header-name}")     private String principalRequestHeader;      @Value("${yourapp.http.auth-token}")     private String principalRequestValue;      @Override     protected void configure(HttpSecurity httpSecurity) throws Exception {         APIKeyAuthFilter filter = new APIKeyAuthFilter(principalRequestHeader);         filter.setAuthenticationManager(new AuthenticationManager() {              @Override             public Authentication authenticate(Authentication authentication) throws AuthenticationException {                 String principal = (String) authentication.getPrincipal();                 if (!principalRequestValue.equals(principal))                 {                     throw new BadCredentialsException("The API key was not found or not the expected value.");                 }                 authentication.setAuthenticated(true);                 return authentication;             }         });         httpSecurity.             antMatcher("/api/**").             csrf().disable().             sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).             and().addFilter(filter).authorizeRequests().anyRequest().authenticated();     }  } 
like image 170
MarkOfHall Avatar answered Sep 25 '22 08:09

MarkOfHall