diff --git a/pom.xml b/pom.xml
index 39b28cc..3ce279d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,11 @@
org.springframework.kafka
spring-kafka
+
+ commons-codec
+ commons-codec
+ 1.15
+
pl.adaptiveapps
service-kafka-model
diff --git a/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtToken.java b/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtToken.java
new file mode 100644
index 0000000..f844f6b
--- /dev/null
+++ b/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtToken.java
@@ -0,0 +1,44 @@
+package pl.adaptiveapps.serviceexternalserver.auth;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class ExtToken extends UsernamePasswordAuthenticationToken {
+ private static final Logger logger = LoggerFactory.getLogger(ExtToken.class);
+ String token;
+ String timestamp;
+
+ public ExtToken(String token, String timestamp) {
+ super(null, null);
+ this.token = token;
+ this.timestamp = timestamp;
+ }
+
+ public boolean validate(String clientToken) {
+ String sha3 = DigestUtils.sha3_512Hex(clientToken + timestamp);
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
+ df.setTimeZone(tz);
+ try {
+ Date parsedTimestamp = df.parse(timestamp);
+ Long timeDiff = parsedTimestamp.getTime() - Timestamp.from(Instant.now()).getTime();
+ System.out.println("Time diff: " + timeDiff);
+ if (Math.abs(timeDiff) > 15000) {
+ return false;
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return token.equals(sha3);
+ }
+}
diff --git a/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtTokenAuthenticationProvider.java b/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtTokenAuthenticationProvider.java
new file mode 100644
index 0000000..8402648
--- /dev/null
+++ b/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtTokenAuthenticationProvider.java
@@ -0,0 +1,36 @@
+package pl.adaptiveapps.serviceexternalserver.auth;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.web.authentication.session.SessionAuthenticationException;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ExtTokenAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(ExtTokenAuthenticationProvider.class);
+
+ @Value( "${ext.client.token}" )
+ private String extToken;
+
+ @Override
+ protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {
+ }
+
+ @Override
+ protected UserDetails retrieveUser(String s, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {
+ ExtToken token = (ExtToken) usernamePasswordAuthenticationToken;
+ if (token.validate(extToken)) {
+ logger.info("Token validated");
+ return new ExtUser();
+ } else {
+ logger.info("Token not valid");
+ throw new SessionAuthenticationException("Invalid token!");
+ }
+ }
+}
diff --git a/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtTokenAuthenticationTokenFilter.java b/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtTokenAuthenticationTokenFilter.java
new file mode 100644
index 0000000..f5e9d4e
--- /dev/null
+++ b/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtTokenAuthenticationTokenFilter.java
@@ -0,0 +1,36 @@
+package pl.adaptiveapps.serviceexternalserver.auth;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class ExtTokenAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {
+ private final static String TOKEN_HEADER = "Authorization";
+ private final static String TIMESTAMP_HEADER = "X-Timestamp";
+ private static final Logger logger = LoggerFactory.getLogger(ExtTokenAuthenticationTokenFilter.class);
+
+ public ExtTokenAuthenticationTokenFilter() {
+ super("/api/**");
+ }
+
+ @Override
+ public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
+ String authToken = httpServletRequest.getHeader(TOKEN_HEADER);
+ String timestamp = httpServletRequest.getHeader(TIMESTAMP_HEADER);
+ return getAuthenticationManager().authenticate(new ExtToken(authToken, timestamp));
+ }
+
+ @Override
+ public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
+ super.successfulAuthentication(request, response, chain, authResult);
+ chain.doFilter(request, response);
+ }
+}
diff --git a/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtUser.java b/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtUser.java
new file mode 100644
index 0000000..c0c0dd1
--- /dev/null
+++ b/src/main/java/pl/adaptiveapps/serviceexternalserver/auth/ExtUser.java
@@ -0,0 +1,49 @@
+package pl.adaptiveapps.serviceexternalserver.auth;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.List;
+
+public class ExtUser implements UserDetails {
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ return List.of(new GrantedAuthority() {
+ @Override
+ public String getAuthority() {
+ return "ADMIN";
+ }
+ });
+ }
+
+ @Override
+ public String getPassword() {
+ return null;
+ }
+
+ @Override
+ public String getUsername() {
+ return "EXT";
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+}
diff --git a/src/main/java/pl/adaptiveapps/serviceexternalserver/config/SecurityConfig.java b/src/main/java/pl/adaptiveapps/serviceexternalserver/config/SecurityConfig.java
new file mode 100644
index 0000000..99baf12
--- /dev/null
+++ b/src/main/java/pl/adaptiveapps/serviceexternalserver/config/SecurityConfig.java
@@ -0,0 +1,54 @@
+package pl.adaptiveapps.serviceexternalserver.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+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.web.authentication.UsernamePasswordAuthenticationFilter;
+import pl.adaptiveapps.serviceexternalserver.auth.ExtTokenAuthenticationProvider;
+import pl.adaptiveapps.serviceexternalserver.auth.ExtTokenAuthenticationTokenFilter;
+
+import java.util.Collections;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ private final ExtTokenAuthenticationProvider extTokenAuthenticationProvider;
+
+ public SecurityConfig(ExtTokenAuthenticationProvider extTokenAuthenticationProvider) {
+ this.extTokenAuthenticationProvider = extTokenAuthenticationProvider;
+ }
+
+ @Override
+ protected AuthenticationManager authenticationManager() {
+ return new ProviderManager(Collections.singletonList(extTokenAuthenticationProvider));
+ }
+
+ private ExtTokenAuthenticationTokenFilter authenticationTokenFilterBean() {
+ ExtTokenAuthenticationTokenFilter authenticationTokenFilter = new ExtTokenAuthenticationTokenFilter();
+ authenticationTokenFilter.setAuthenticationManager(authenticationManager());
+ authenticationTokenFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
+ });
+ return authenticationTokenFilter;
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .csrf().disable()
+ .authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll()
+ .antMatchers("/api/**").authenticated()
+ .and()
+ .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
+ http
+ .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
+ }
+
+}