Skip to content
Snippets Groups Projects
Commit 8ff897c5 authored by Martin Weise's avatar Martin Weise
Browse files

WIP: Added security to database service

Former-commit-id: 88043b7e
parent cf87a481
Branches
Tags
1 merge request!42Fixed the query service tests
Showing
with 250 additions and 3 deletions
......@@ -51,6 +51,15 @@
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>${spring-cloud.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Data Source -->
<dependency>
<groupId>org.springframework.boot</groupId>
......
......@@ -2,7 +2,6 @@ package at.tuwien.auth;
import at.tuwien.gateway.AuthenticationServiceGateway;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
......
......@@ -46,6 +46,15 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- elasticsearch -->
<dependency>
<groupId>org.springframework.data</groupId>
......
......@@ -31,3 +31,4 @@ eureka:
fda:
elastic.endpoint: fda-search-service:9200
ready.path: /ready
auth.endpoint: http://fda-authentication-service:9097
\ No newline at end of file
......@@ -31,3 +31,4 @@ eureka:
fda:
elastic.endpoint: localhost:9200
ready.path: ./ready
auth.endpoint: http://localhost:9097
\ No newline at end of file
package at.tuwien.auth;
import at.tuwien.gateway.AuthenticationServiceGateway;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
public class AuthTokenFilter extends OncePerRequestFilter {
private final AuthenticationServiceGateway authenticationServiceGateway;
public AuthTokenFilter(AuthenticationServiceGateway authenticationServiceGateway) {
this.authenticationServiceGateway = authenticationServiceGateway;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String jwt = parseJwt(request);
log.debug("parsed jwt {}", jwt);
if (jwt != null) {
final UserDetails userDetails = authenticationServiceGateway.validate(jwt);
final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(request, response);
}
/**
* Parses the token from the HTTP header of the request
*
* @param request The request.
* @return The token.
*/
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
return headerAuth.substring(7, headerAuth.length());
}
return null;
}
}
\ No newline at end of file
package at.tuwien.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
@Configuration
public class GatewayConfig {
@Value("${fda.auth.endpoint}")
private String authEndpoint;
@Bean
public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(authEndpoint));
return restTemplate;
}
}
package at.tuwien.config;
import at.tuwien.auth.AuthTokenFilter;
import at.tuwien.gateway.AuthenticationServiceGateway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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 org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import javax.servlet.http.HttpServletResponse;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final AuthenticationServiceGateway authenticationServiceGateway;
@Autowired
public WebSecurityConfig(AuthenticationServiceGateway authenticationServiceGateway) {
this.authenticationServiceGateway = authenticationServiceGateway;
}
@Bean
public AuthTokenFilter authTokenFilter() {
return new AuthTokenFilter(authenticationServiceGateway);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
/* enable CORS and disable CSRF */
http = http.cors().and().csrf().disable();
/* set session management to stateless */
http = http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and();
/* set unauthorized requests exception handler */
http = http
.exceptionHandling()
.authenticationEntryPoint(
(request, response, ex) -> {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
ex.getMessage()
);
}
).and();
/* set permissions on endpoints */
http.authorizeRequests()
/* our public endpoints */
.antMatchers(HttpMethod.GET, "/api/container/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/image/**").permitAll()
/* our private endpoints */
.anyRequest().authenticated();
/* add JWT token filter */
http.addFilterBefore(authTokenFilter(),
UsernamePasswordAuthenticationFilter.class
);
}
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
package at.tuwien.gateway;
import org.springframework.security.core.userdetails.UserDetails;
public interface AuthenticationServiceGateway {
/**
* Validates a token
*
* @param token The token
* @return User details on success
*/
UserDetails validate(String token);
}
package at.tuwien.gateway.impl;
import at.tuwien.api.user.UserDto;
import at.tuwien.gateway.AuthenticationServiceGateway;
import at.tuwien.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class AuthenticationServiceGatewayImpl implements AuthenticationServiceGateway {
private final UserMapper userMapper;
private final RestTemplate restTemplate;
@Autowired
public AuthenticationServiceGatewayImpl(UserMapper userMapper, RestTemplate restTemplate) {
this.userMapper = userMapper;
this.restTemplate = restTemplate;
}
@Override
public UserDetails validate(String token) {
final HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + token);
final ResponseEntity<UserDto> response = restTemplate.exchange("/api/auth", HttpMethod.PUT,
new HttpEntity<>("", headers), UserDto.class);
return userMapper.userDtoToUserDetailsDto(response.getBody());
}
}
package at.tuwien.mapper;
import at.tuwien.api.user.GrantedAuthorityDto;
import at.tuwien.api.user.UserDetailsDto;
import at.tuwien.api.user.UserDto;
import org.mapstruct.Mapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@Mapper(componentModel = "spring")
public interface UserMapper {
UserDetailsDto userDtoToUserDetailsDto(UserDto data);
default GrantedAuthority grantedAuthorityDtoToGrantedAuthority(GrantedAuthorityDto data) {
return new SimpleGrantedAuthority(data.getAuthority());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment