From a78c978c9b5476cf3df22eb54876feea00103729 Mon Sep 17 00:00:00 2001 From: Hamid Reza Sharifi Date: Thu, 18 May 2023 12:20:26 +0330 Subject: [PATCH] BAEL-5711: Securing Spring Boot API with API key and secret (#14015) * #bael-5711: add source * #bael-5711: remove extra space * #bael-5711: remove extra space * #bael-5711: remove extra space --------- Co-authored-by: h_sharifi --- .../ApiKeySecretAuthApplication.java | 14 ++++++++ .../configuration/ApiKeyAuthentication.java | 25 ++++++++++++++ .../configuration/AuthenticationFilter.java | 22 ++++++++++++ .../configuration/AuthenticationService.java | 20 +++++++++++ .../configuration/SecurityConfig.java | 34 +++++++++++++++++++ .../controller/ResourceController.java | 12 +++++++ 6 files changed, 127 insertions(+) create mode 100644 spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/ApiKeySecretAuthApplication.java create mode 100644 spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/ApiKeyAuthentication.java create mode 100644 spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationFilter.java create mode 100644 spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationService.java create mode 100644 spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/SecurityConfig.java create mode 100644 spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/controller/ResourceController.java diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/ApiKeySecretAuthApplication.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/ApiKeySecretAuthApplication.java new file mode 100644 index 0000000000..6dea68f07b --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/ApiKeySecretAuthApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.apikeyauthentication; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; + +@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class}) +public class ApiKeySecretAuthApplication { + + public static void main(String[] args) { + SpringApplication.run(ApiKeySecretAuthApplication.class, args); + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/ApiKeyAuthentication.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/ApiKeyAuthentication.java new file mode 100644 index 0000000000..6f2a78bd4a --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/ApiKeyAuthentication.java @@ -0,0 +1,25 @@ +package com.baeldung.apikeyauthentication.configuration; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import java.util.Collection; + +public class ApiKeyAuthentication extends AbstractAuthenticationToken { + private final String apiKey; + + public ApiKeyAuthentication(String apiKey, Collection authorities) { + super(authorities); + this.apiKey = apiKey; + setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getPrincipal() { + return apiKey; + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationFilter.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationFilter.java new file mode 100644 index 0000000000..6c82f9c9ef --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationFilter.java @@ -0,0 +1,22 @@ +package com.baeldung.apikeyauthentication.configuration; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.GenericFilterBean; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +public class AuthenticationFilter extends GenericFilterBean { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) + throws IOException, ServletException { + Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest) request); + SecurityContextHolder.getContext().setAuthentication(authentication); + filterChain.doFilter(request, response); + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationService.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationService.java new file mode 100644 index 0000000000..14183f9f62 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationService.java @@ -0,0 +1,20 @@ +package com.baeldung.apikeyauthentication.configuration; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.AuthorityUtils; +import javax.servlet.http.HttpServletRequest; + +public class AuthenticationService { + + private static final String AUTH_TOKEN_HEADER_NAME = "X-API-KEY"; + private static final String AUTH_TOKEN = "Baeldung"; + + public static Authentication getAuthentication(HttpServletRequest request) { + String apiKey = request.getHeader(AUTH_TOKEN_HEADER_NAME); + if (apiKey != null && apiKey.equals(AUTH_TOKEN)) { + return new ApiKeyAuthentication(apiKey, AuthorityUtils.NO_AUTHORITIES); + } + + return null; + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/SecurityConfig.java new file mode 100644 index 0000000000..0ce58d1bf8 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/SecurityConfig.java @@ -0,0 +1,34 @@ +package com.baeldung.apikeyauthentication.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .authorizeRequests() + .antMatchers("/**") + .authenticated() + .and() + .httpBasic() + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .addFilterBefore(new AuthenticationFilter(), + UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/controller/ResourceController.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/controller/ResourceController.java new file mode 100644 index 0000000000..56164a14a0 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/controller/ResourceController.java @@ -0,0 +1,12 @@ +package com.baeldung.apikeyauthentication.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ResourceController { + @GetMapping("/home") + public String homeEndpoint() { + return "Baeldung !"; + } +}