Merge branch 'DEVELOP' of ssh://git.eclipse.org:29418/openk-usermodules/org.eclipse.openk-usermodules.contactBaseData.backend into KON_110-SpringSecurity
diff --git a/pom.xml b/pom.xml
index dcabe5e..4a33097 100644
--- a/pom.xml
+++ b/pom.xml
@@ -89,6 +89,11 @@
<version>${openfeign.version}</version>
</dependency>
<dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
+ <version>${openfeign.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${keycloak-core.version}</version>
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/ContactBaseDataApplication.java b/src/main/java/org/eclipse/openk/contactbasedata/ContactBaseDataApplication.java
index 45920d5..9705382 100644
--- a/src/main/java/org/eclipse/openk/contactbasedata/ContactBaseDataApplication.java
+++ b/src/main/java/org/eclipse/openk/contactbasedata/ContactBaseDataApplication.java
@@ -16,10 +16,12 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@EnableSwagger2
+@EnableFeignClients
public class ContactBaseDataApplication {
public static void main(String[] args) {
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/api/AuthNAuthApi.java b/src/main/java/org/eclipse/openk/contactbasedata/api/AuthNAuthApi.java
index 0fee847..3dbfb09 100644
--- a/src/main/java/org/eclipse/openk/contactbasedata/api/AuthNAuthApi.java
+++ b/src/main/java/org/eclipse/openk/contactbasedata/api/AuthNAuthApi.java
@@ -4,10 +4,9 @@
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
-@FeignClient(name = "${services.auth-n-auth.name}")
+@FeignClient(name = "${services.authNAuth.name}")
public interface AuthNAuthApi {
-
@GetMapping(value= "/portal/rest/beservice/checkAuth")
feign.Response isTokenValid(@RequestHeader("Authorization") String token );
}
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/config/SecurityConfig.java b/src/main/java/org/eclipse/openk/contactbasedata/config/SecurityConfig.java
index ad85744..6897d28 100644
--- a/src/main/java/org/eclipse/openk/contactbasedata/config/SecurityConfig.java
+++ b/src/main/java/org/eclipse/openk/contactbasedata/config/SecurityConfig.java
@@ -16,6 +16,7 @@
import org.eclipse.openk.contactbasedata.config.auth.JwtAuthenticationEntryPoint;
import org.eclipse.openk.contactbasedata.config.auth.JwtAuthenticationTokenFilter;
+import org.eclipse.openk.contactbasedata.config.auth.JwtTokenValidationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
@@ -37,6 +38,9 @@
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Autowired
+ private JwtTokenValidationFilter jwtTokenValidationFilter;
+
+ @Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Override
@@ -57,6 +61,9 @@
.formLogin().disable()
.anonymous()
.and()
+ .addFilterAfter(jwtTokenValidationFilter, BasicAuthenticationFilter.class)
+ .anonymous()
+ .and()
.addFilterAfter(jwtAuthenticationTokenFilter, BasicAuthenticationFilter.class);
}
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/config/auth/JwtTokenValidationFilter.java b/src/main/java/org/eclipse/openk/contactbasedata/config/auth/JwtTokenValidationFilter.java
new file mode 100644
index 0000000..fe57506
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/contactbasedata/config/auth/JwtTokenValidationFilter.java
@@ -0,0 +1,63 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************
+*/
+
+package org.eclipse.openk.contactbasedata.config.auth;
+
+import feign.Response;
+import lombok.extern.log4j.Log4j2;
+import org.eclipse.openk.contactbasedata.api.AuthNAuthApi;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+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 javax.servlet.http.HttpServletResponseWrapper;
+import java.io.IOException;
+
+@Component
+@Log4j2
+public class JwtTokenValidationFilter extends OncePerRequestFilter {
+ @Autowired
+ private AuthNAuthApi authNAuthApi;
+
+ @Value("${jwt.useStaticJwt}")
+ private boolean useStaticJwt;
+
+ @Value("${jwt.tokenHeader}")
+ private String tokenHeader;
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+ String authenticationHeader = useStaticJwt ? null : request.getHeader(this.tokenHeader);
+
+ if(authenticationHeader != null) {
+ final String bearerTkn= authenticationHeader.replace("Bearer ", "");
+ Response res = authNAuthApi.isTokenValid(bearerTkn);
+ if( res.status() != HttpStatus.OK.value() ) {
+ final HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse)response);
+ wrapper.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token expired or not valid");
+ chain.doFilter(request, wrapper.getResponse());
+
+ return;
+ }
+ }
+ chain.doFilter(request, response);
+ }
+}
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/exceptions/UnauthorizedException.java b/src/main/java/org/eclipse/openk/contactbasedata/exceptions/UnauthorizedException.java
new file mode 100644
index 0000000..ab9864e
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/contactbasedata/exceptions/UnauthorizedException.java
@@ -0,0 +1,16 @@
+package org.eclipse.openk.contactbasedata.exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(code = HttpStatus.UNAUTHORIZED)
+public class UnauthorizedException extends RuntimeException{
+
+ public UnauthorizedException() {
+
+ }
+
+ public UnauthorizedException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 8a19aac..1a60136 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -27,7 +27,7 @@
staticJwt: x
services:
- auth-n-auth:
+ authNAuth:
name: authNAuthService
authNAuthService:
diff --git a/src/main/resources/application_localdev.yml b/src/main/resources/application_localdev.yml
index 862c649..665fbec 100644
--- a/src/main/resources/application_localdev.yml
+++ b/src/main/resources/application_localdev.yml
@@ -29,3 +29,12 @@
tokenHeader: Authorization
useStaticJwt: true
staticJwt: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJIYlI3Z2pobmE2eXJRZnZJTWhUSV9tY2g3ZmtTQWVFX3hLTjBhZVl0bjdjIn0.eyJqdGkiOiI5MGI0NGFkOC1iYjlmLTQ1MzktYTQwYy0yYjQyZTNkNjNiOGEiLCJleHAiOjE1Nzg2NTU3OTUsIm5iZiI6MCwiaWF0IjoxNTc4NjU1NDk1LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvRWxvZ2Jvb2siLCJhdWQiOiJlbG9nYm9vay1iYWNrZW5kIiwic3ViIjoiODYyNjY5NmYtZjFhMi00ZGI1LTkyZWYtZTlhMjQ2Njg1YTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiZWxvZ2Jvb2stYmFja2VuZCIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjJmMWIzODE5LWZjNjQtNDEzNC1iNWQxLWY3ZWY4NzU5NDBkNCIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiKiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsia29uLWFkbWluIiwia29uLXdyaXRlciIsImtvbi1hY2Nlc3MiLCJrb24tcmVhZGVyIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnt9LCJuYW1lIjoiVGVzdGVyRmlyc3RuYW1lX3J3YSBUZXN0ZXJMYXN0bmFtZV9yd2EiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ0ZXN0dXNlcl9yd2EiLCJnaXZlbl9uYW1lIjoiVGVzdGVyRmlyc3RuYW1lX3J3YSIsImZhbWlseV9uYW1lIjoiVGVzdGVyTGFzdG5hbWVfcndhIn0.DAYXuv4tKn8RXqO1jyttnD-tF4nShUBQyfe4bKbAiPAyY2x5YbAf3M4eXnLrGqo8-loGKldICC28bL0LaMA3KKkQEOfW5sfpGqoN6212vs89mOklt0TJYc5PMXwFgJ5WC_TKjdwq7-aaDafOEWehV0U1ut3s-94ovNYIEn29nzXm2W1ldoXJEq03F880jlysQ5zlRvGF7eXEEpFfI2URyyNQ2UWh0Ssfq-gOAt2pbF1u6prA5RfvUmZ3v1eu21YLGZtgqPqxb1l6odyH3ip15j_HdgnTeo52ymxuRUj65Mskme3V5ev2DitHI9vZgnpV8Idhb4TTWliBeGCOMfDFCg
+
+services:
+ authNAuth:
+ name: authNAuthService
+
+authNAuthService:
+ ribbon:
+ listOfServers: http://entopkon:8880
+