...
parent
2d2a9e8909
commit
e87736fd26
5
pom.xml
5
pom.xml
|
|
@ -29,6 +29,11 @@
|
||||||
<groupId>org.springframework.kafka</groupId>
|
<groupId>org.springframework.kafka</groupId>
|
||||||
<artifactId>spring-kafka</artifactId>
|
<artifactId>spring-kafka</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>1.15</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pl.adaptiveapps</groupId>
|
<groupId>pl.adaptiveapps</groupId>
|
||||||
<artifactId>service-kafka-model</artifactId>
|
<artifactId>service-kafka-model</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue