From c5cb48f99562d22bb83c2bdb3e4b3f6df95c8149 Mon Sep 17 00:00:00 2001
From: unknown <Jerrypan44@gmail.com>
Date: Tue, 5 Nov 2019 15:35:59 +0200
Subject: [PATCH 1/9] initial wip

---
 pom.xml                                            | 12 ++++++++++++
 src/main/application.properties                    | 14 ++++++++++++++
 .../mip/configuration/SecurityConfiguration.java   | 11 ++++++++---
 3 files changed, 34 insertions(+), 3 deletions(-)
 create mode 100644 src/main/application.properties

diff --git a/pom.xml b/pom.xml
index 33287a67e..1d8ac0d6c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -249,6 +249,18 @@
             <artifactId>java-jwt</artifactId>
             <version>3.8.3</version>
         </dependency>
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>3.8.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-spring-boot-2-starter</artifactId>
+            <version>4.0.0.Final</version>
+        </dependency>
+
+
     </dependencies>
 
     <build>
diff --git a/src/main/application.properties b/src/main/application.properties
new file mode 100644
index 000000000..a2a68cdc6
--- /dev/null
+++ b/src/main/application.properties
@@ -0,0 +1,14 @@
+keycloak.realm=Demo
+keycloak.resource=vanilla
+keycloak.auth-server-url=http://localhost:8080/auth
+keycloak.ssl-required=external
+keycloak.public-client=true
+
+#keycloak.securityConstraints[0].authRoles[0]=Member
+#keycloak.securityConstraints[0].authRoles[1]=Librarian
+#keycloak.securityConstraints[0].securityCollections[0].name=member resource
+#keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/books
+
+#keycloak.securityConstraints[1].authRoles[0]=Librarian
+#keycloak.securityConstraints[1].securityCollections[0].name=librarian resource
+#keycloak.securityConstraints[1].securityCollections[0].patterns[0]=/manager
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index d8ec1acfb..adacd7a81 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -88,6 +88,9 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
     @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
     private String revokeTokenURI;
 
+    @Autowired
+    private HttpServletRequest request;
+
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         // @formatter:off
@@ -108,9 +111,11 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
                     .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
         }
         else {
-            http.antMatcher("/**")
-                    .authorizeRequests()
-                    .antMatchers("/**").permitAll().and().csrf().disable();
+            //keycloak
+            (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
+//            http.antMatcher("/**")
+//                    .authorizeRequests()
+//                    .antMatchers("/**").permitAll().and().csrf().disable();
         }
     }
 
-- 
GitLab


From eb06a4b0cdae8563c20718a817a28db859347853 Mon Sep 17 00:00:00 2001
From: unknown <Jerrypan44@gmail.com>
Date: Tue, 5 Nov 2019 16:24:57 +0200
Subject: [PATCH 2/9] change configuration

---
 src/main/application.properties     | 14 --------------
 src/main/resources/application.conf |  8 ++++++++
 2 files changed, 8 insertions(+), 14 deletions(-)
 delete mode 100644 src/main/application.properties

diff --git a/src/main/application.properties b/src/main/application.properties
deleted file mode 100644
index a2a68cdc6..000000000
--- a/src/main/application.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-keycloak.realm=Demo
-keycloak.resource=vanilla
-keycloak.auth-server-url=http://localhost:8080/auth
-keycloak.ssl-required=external
-keycloak.public-client=true
-
-#keycloak.securityConstraints[0].authRoles[0]=Member
-#keycloak.securityConstraints[0].authRoles[1]=Librarian
-#keycloak.securityConstraints[0].securityCollections[0].name=member resource
-#keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/books
-
-#keycloak.securityConstraints[1].authRoles[0]=Librarian
-#keycloak.securityConstraints[1].securityCollections[0].name=librarian resource
-#keycloak.securityConstraints[1].securityCollections[0].patterns[0]=/manager
\ No newline at end of file
diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf
index e2abfd5ae..61b39c873 100644
--- a/src/main/resources/application.conf
+++ b/src/main/resources/application.conf
@@ -6,6 +6,14 @@ app {
   clusterSystemName = ${clustering.cluster.name}
 }
 
+keycloak {
+    realm=Demo
+    resource=vanilla
+    auth-server-url=http://localhost:8080/auth
+    ssl-required=external
+    public-client=true
+}
+
 clustering {
   ip = "127.0.0.1"
   ip = ${?CLUSTER_IP}
-- 
GitLab


From 071465bebde8075ec33c50a6e5e1d9f0ed156339 Mon Sep 17 00:00:00 2001
From: unknown <Jerrypan44@gmail.com>
Date: Wed, 6 Nov 2019 14:48:25 +0200
Subject: [PATCH 3/9] keycloak wip

---
 .../mip/configuration/KeycloakConfiguration.java   | 14 ++++++++++++++
 .../mip/configuration/SecurityConfiguration.java   |  6 +++---
 2 files changed, 17 insertions(+), 3 deletions(-)
 create mode 100644 src/main/java/eu/hbp/mip/configuration/KeycloakConfiguration.java

diff --git a/src/main/java/eu/hbp/mip/configuration/KeycloakConfiguration.java b/src/main/java/eu/hbp/mip/configuration/KeycloakConfiguration.java
new file mode 100644
index 000000000..45c598924
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/configuration/KeycloakConfiguration.java
@@ -0,0 +1,14 @@
+package eu.hbp.mip.configuration;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import org.keycloak.KeycloakSecurityContext;
+
+public class KeycloakConfiguration {
+
+    @Autowired
+    private HttpServletRequest request;
+    public KeycloakSecurityContext getKeycloakSecurityContext() {
+        return (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index adacd7a81..3d0a49357 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -88,8 +88,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
     @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
     private String revokeTokenURI;
 
-    @Autowired
-    private HttpServletRequest request;
+//    @Autowired
+//    private HttpServletRequest request;
 
     @Override
     protected void configure(HttpSecurity http) throws Exception {
@@ -112,7 +112,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
         }
         else {
             //keycloak
-            (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
+            KeycloakConfiguration.getKeycloakSecurityContext();
 //            http.antMatcher("/**")
 //                    .authorizeRequests()
 //                    .antMatchers("/**").permitAll().and().csrf().disable();
-- 
GitLab


From a8a6d692d56b25057f38fdaef3ebca12728613b7 Mon Sep 17 00:00:00 2001
From: unknown <Jerrypan44@gmail.com>
Date: Mon, 11 Nov 2019 18:01:06 +0200
Subject: [PATCH 4/9] keycloak wip

---
 build.sh                                      |   4 +-
 pom.xml                                       |  15 +-
 .../configuration/SecurityConfiguration.java  | 367 ++++++++++--------
 3 files changed, 218 insertions(+), 168 deletions(-)

diff --git a/build.sh b/build.sh
index 5df0e1ce8..752b95924 100755
--- a/build.sh
+++ b/build.sh
@@ -34,9 +34,9 @@ docker build --build-arg BUILD_DATE=$(date -Iseconds) \
     --build-arg VCS_REF=$VCS_REF \
     --build-arg VERSION=$VERSION \
     --tag "$IMAGE:latest" \
-    --tag "$IMAGE:$VERSION" \
+    --tag "jerrypan44/portal-backend:latest" \
     .
-
+docker push "jerrypan44/portal-backend:latest"
 BUGSNAG_KEY=""
 eval $(grep -e "^\\s*BUGSNAG_KEY" Dockerfile | tr '\\' ' ')
 
diff --git a/pom.xml b/pom.xml
index 1d8ac0d6c..d206d2ad2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,6 +16,7 @@
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>1.3.8.RELEASE</version>
         <relativePath/>
+
     </parent>
 
     <properties>
@@ -256,8 +257,7 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-spring-boot-2-starter</artifactId>
-            <version>4.0.0.Final</version>
+            <artifactId>keycloak-spring-boot-starter</artifactId>
         </dependency>
 
 
@@ -354,4 +354,15 @@
       </plugins>
     </build>
 
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.keycloak.bom</groupId>
+                <artifactId>keycloak-adapter-bom</artifactId>
+                <version>7.0.0</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
 </project>
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 3d0a49357..ba6a380de 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -49,177 +49,216 @@ import java.io.IOException;
 /**
  * Configuration for security.
  */
-@Configuration
-@EnableOAuth2Client
-public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
-
+@KeycloakConfiguration
+public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
     @Autowired
-    private OAuth2ClientContext oauth2ClientContext;
-
-    /**
-     * Enable HBP collab authentication (1) or disable it (0). Default is 1
-     */
-    @Value("#{'${hbp.authentication.enabled:1}'}")
-    private boolean authentication;
-
-    /**
-     * Absolute URL to redirect to when login is required
-     */
-    @Value("#{'${frontend.loginUrl:/login/hbp}'}")
-    private String loginUrl;
-
-    /**
-     * Absolute URL to redirect to after successful login
-     */
-    @Value("#{'${frontend.redirectAfterLoginUrl:http://frontend/home}'}")
-    private String frontendRedirectAfterLogin;
-
-    /**
-     * Absolute URL to redirect to after logout has occurred
-     */
-    @Value("#{'${frontend.redirectAfterLogoutUrl:/login/hbp}'}")
-    private String redirectAfterLogoutUrl;
+    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+        auth.authenticationProvider(keycloakAuthenticationProvider());
+    }
 
     /**
-     * URL to revoke auth token
+     * Defines the session authentication strategy.
      */
-    @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
-    private String revokeTokenURI;
-
-//    @Autowired
-//    private HttpServletRequest request;
-
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
-        // @formatter:off
-        http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
-
-        if (authentication) {
-            http.antMatcher("/**")
-                    .authorizeRequests()
-                    .antMatchers(
-                            "/", "/login/**", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs", "/swagger-ui.html", "/swagger-resources/**"
-                    ).permitAll()
-                    .anyRequest().authenticated()
-                    .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
-                    .and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
-                    .and().logout().permitAll()
-                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
-                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
-                    .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
-        }
-        else {
-            //keycloak
-            KeycloakConfiguration.getKeycloakSecurityContext();
-//            http.antMatcher("/**")
-//                    .authorizeRequests()
-//                    .antMatchers("/**").permitAll().and().csrf().disable();
-        }
-    }
-
-    private Filter ssoFilter() {
-        OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
-        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
-        hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
-        hbpFilter.setRestTemplate(hbpTemplate);
-        hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId()));
-        return hbpFilter;
-    }
-
     @Bean
-    public FilterRegistrationBean oauth2ClientFilterRegistration(
-            OAuth2ClientContextFilter filter) {
-        FilterRegistrationBean registration = new FilterRegistrationBean();
-        registration.setFilter(filter);
-        registration.setOrder(-100);
-        return registration;
-    }
-
-    @Bean(name="hbp")
-    @ConfigurationProperties("hbp.client")
-    public OAuth2ProtectedResourceDetails hbp() {
-        return new AuthorizationCodeResourceDetails();
-    }
-
-    @Bean(name="hbpResource")
-    @ConfigurationProperties("hbp.resource")
-    public ResourceServerProperties hbpResource() {
-        return new ResourceServerProperties();
-    }
-
-    public boolean isAuthentication() {
-        return authentication;
-    }
-
-    public String getFrontendRedirectAfterLogin() {
-        return frontendRedirectAfterLogin;
-    }
-
-    private Filter csrfHeaderFilter() {
-        return new OncePerRequestFilter() {
-            @Override
-            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
-                                            FilterChain filterChain) throws ServletException, IOException {
-                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
-                if (csrf != null) {
-                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
-                    String token = csrf.getToken();
-                    if (cookie == null || token != null && !token.equals(cookie.getValue())) {
-                        cookie = new Cookie("XSRF-TOKEN", token);
-                        cookie.setPath("/");
-                        response.addCookie(cookie);
-                    }
-                }
-                filterChain.doFilter(request, response);
-            }
-        };
+    @Override
+    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
+        return new NullAuthenticatedSessionStrategy();
     }
 
-    private CsrfTokenRepository csrfTokenRepository() {
-        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
-        repository.setHeaderName("X-XSRF-TOKEN");
-        return repository;
+    @Override
+    protected void configure(HttpSecurity http) throws Exception
+    {
+        super.configure(http);
+        http
+                .authorizeRequests()
+                .antMatchers("/user*").authenticated()
+                .antMatchers("/public1*").hasAuthority("public13")
+                .antMatchers("/public2*").hasAuthority("public2")
+                .antMatchers("/public3*").hasAuthority("public3")
+                .antMatchers("/admin*").authenticated()
+                .anyRequest().permitAll()
+                .and()
+                .logout()
+                .addLogoutHandler(keycloakLogoutHandler())//.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
+                .logoutUrl("/logout").permitAll()
+                .logoutSuccessUrl("/");
+//        .anyRequest().permitAll().and().logout().addLogoutHandler(new KeycloakLogoutHandler(new RestTemplate())).logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
+        ;
     }
 
-    private class CustomLogoutHandler implements LogoutHandler {
-        @Override
-        public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
-
-            // Hackish way of accessing to this information...
-            final UserInfo userInfo = (UserInfo) httpServletRequest.getSession().getAttribute("userInfo");
-            if (userInfo != null) {
-                userInfo.setFakeAuth(false);
-            }
-
-            if (oauth2ClientContext == null || oauth2ClientContext.getAccessToken() == null)
-            {
-                return;
-            }
-
-            String idToken = oauth2ClientContext.getAccessToken().getAdditionalInformation().get("id_token").toString();
-
-            StringBuilder query = new StringBuilder();
-            query.append("{");
-            query.append("\"token\":");
-            query.append("\"").append(idToken).append("\"");
-            query.append("}");
-
-            try {
-                int responseCode = HTTPUtil.sendPost(revokeTokenURI, query.toString(), new StringBuilder());
-                if (responseCode != 200)
-                {
-                    LOGGER.warn("Cannot send request to OIDC server for revocation ! ");
-                }
-                else{
-                    LOGGER.info("Should be logged out");
-                }
-            } catch (IOException e) {
-                LOGGER.warn("Cannot notify logout to OIDC server !");
-                LOGGER.trace("Cannot notify logout", e);
-            }
-
-        }
-    }
 }
+
+//@Configuration
+//@EnableOAuth2Client
+//public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
+//
+//    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
+//
+//    @Autowired
+//    private OAuth2ClientContext oauth2ClientContext;
+//
+//    /**
+//     * Enable HBP collab authentication (1) or disable it (0). Default is 1
+//     */
+//    @Value("#{'${hbp.authentication.enabled:1}'}")
+//    private boolean authentication;
+//
+//    /**
+//     * Absolute URL to redirect to when login is required
+//     */
+//    @Value("#{'${frontend.loginUrl:/login/hbp}'}")
+//    private String loginUrl;
+//
+//    /**
+//     * Absolute URL to redirect to after successful login
+//     */
+//    @Value("#{'${frontend.redirectAfterLoginUrl:http://frontend/home}'}")
+//    private String frontendRedirectAfterLogin;
+//
+//    /**
+//     * Absolute URL to redirect to after logout has occurred
+//     */
+//    @Value("#{'${frontend.redirectAfterLogoutUrl:/login/hbp}'}")
+//    private String redirectAfterLogoutUrl;
+//
+//    /**
+//     * URL to revoke auth token
+//     */
+//    @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
+//    private String revokeTokenURI;
+//
+////    @Autowired
+////    private HttpServletRequest request;
+//
+//    @Override
+//    protected void configure(HttpSecurity http) throws Exception {
+//        // @formatter:off
+//        http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
+//
+//        if (authentication) {
+//            http.antMatcher("/**")
+//                    .authorizeRequests()
+//                    .antMatchers(
+//                            "/", "/login/**", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs", "/swagger-ui.html", "/swagger-resources/**"
+//                    ).permitAll()
+//                    .anyRequest().authenticated()
+//                    .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
+//                    .and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
+//                    .and().logout().permitAll()
+//                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
+//                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
+//                    .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
+//        }
+//        else {
+//            //keycloak
+//            //KeycloakConfiguration.getKeycloakSecurityContext();
+////            http.antMatcher("/**")
+////                    .authorizeRequests()
+////                    .antMatchers("/**").permitAll().and().csrf().disable();
+//        }
+//    }
+//
+//    private Filter ssoFilter() {
+//        OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
+//        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
+//        hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
+//        hbpFilter.setRestTemplate(hbpTemplate);
+//        hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId()));
+//        return hbpFilter;
+//    }
+//
+//    @Bean
+//    public FilterRegistrationBean oauth2ClientFilterRegistration(
+//            OAuth2ClientContextFilter filter) {
+//        FilterRegistrationBean registration = new FilterRegistrationBean();
+//        registration.setFilter(filter);
+//        registration.setOrder(-100);
+//        return registration;
+//    }
+//
+//    @Bean(name="hbp")
+//    @ConfigurationProperties("hbp.client")
+//    public OAuth2ProtectedResourceDetails hbp() {
+//        return new AuthorizationCodeResourceDetails();
+//    }
+//
+//    @Bean(name="hbpResource")
+//    @ConfigurationProperties("hbp.resource")
+//    public ResourceServerProperties hbpResource() {
+//        return new ResourceServerProperties();
+//    }
+//
+//    public boolean isAuthentication() {
+//        return authentication;
+//    }
+//
+//    public String getFrontendRedirectAfterLogin() {
+//        return frontendRedirectAfterLogin;
+//    }
+//
+//    private Filter csrfHeaderFilter() {
+//        return new OncePerRequestFilter() {
+//            @Override
+//            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
+//                                            FilterChain filterChain) throws ServletException, IOException {
+//                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
+//                if (csrf != null) {
+//                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
+//                    String token = csrf.getToken();
+//                    if (cookie == null || token != null && !token.equals(cookie.getValue())) {
+//                        cookie = new Cookie("XSRF-TOKEN", token);
+//                        cookie.setPath("/");
+//                        response.addCookie(cookie);
+//                    }
+//                }
+//                filterChain.doFilter(request, response);
+//            }
+//        };
+//    }
+//
+//    private CsrfTokenRepository csrfTokenRepository() {
+//        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
+//        repository.setHeaderName("X-XSRF-TOKEN");
+//        return repository;
+//    }
+//
+//    private class CustomLogoutHandler implements LogoutHandler {
+//        @Override
+//        public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
+//
+//            // Hackish way of accessing to this information...
+//            final UserInfo userInfo = (UserInfo) httpServletRequest.getSession().getAttribute("userInfo");
+//            if (userInfo != null) {
+//                userInfo.setFakeAuth(false);
+//            }
+//
+//            if (oauth2ClientContext == null || oauth2ClientContext.getAccessToken() == null)
+//            {
+//                return;
+//            }
+//
+//            String idToken = oauth2ClientContext.getAccessToken().getAdditionalInformation().get("id_token").toString();
+//
+//            StringBuilder query = new StringBuilder();
+//            query.append("{");
+//            query.append("\"token\":");
+//            query.append("\"").append(idToken).append("\"");
+//            query.append("}");
+//
+//            try {
+//                int responseCode = HTTPUtil.sendPost(revokeTokenURI, query.toString(), new StringBuilder());
+//                if (responseCode != 200)
+//                {
+//                    LOGGER.warn("Cannot send request to OIDC server for revocation ! ");
+//                }
+//                else{
+//                    LOGGER.info("Should be logged out");
+//                }
+//            } catch (IOException e) {
+//                LOGGER.warn("Cannot notify logout to OIDC server !");
+//                LOGGER.trace("Cannot notify logout", e);
+//            }
+//
+//        }
+//    }
+//}
-- 
GitLab


From 9e28626ec653e845442dd33d505df2a1b442920d Mon Sep 17 00:00:00 2001
From: jerrypan44 <jerrypan44@gmail.com>
Date: Tue, 12 Nov 2019 11:29:31 +0000
Subject: [PATCH 5/9] adding build file

---
 build.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/build.sh b/build.sh
index 5df0e1ce8..beeee73c9 100755
--- a/build.sh
+++ b/build.sh
@@ -34,8 +34,10 @@ docker build --build-arg BUILD_DATE=$(date -Iseconds) \
     --build-arg VCS_REF=$VCS_REF \
     --build-arg VERSION=$VERSION \
     --tag "$IMAGE:latest" \
-    --tag "$IMAGE:$VERSION" \
+    --tag "jerrypan44/portal-backend:latest" \
     .
+	
+docker push "jerrypan44/portal-backend:latest"
 
 BUGSNAG_KEY=""
 eval $(grep -e "^\\s*BUGSNAG_KEY" Dockerfile | tr '\\' ' ')
-- 
GitLab


From 2b7084920c5e49cd35b37adf1b3c619e10db30d6 Mon Sep 17 00:00:00 2001
From: jerrypan44 <jerrypan44@gmail.com>
Date: Fri, 22 Nov 2019 15:35:02 +0000
Subject: [PATCH 6/9] WIP committed working features roles and keycloak
 integration

---
 docker/config/application.tmpl                |   5 +-
 pom.xml                                       |   6 -
 .../configuration/KeycloakConfiguration.java  |  14 -
 .../configuration/SecurityConfiguration.java  | 417 +++++++++---------
 .../eu/hbp/mip/controllers/SecurityApi.java   |   2 +
 5 files changed, 213 insertions(+), 231 deletions(-)
 delete mode 100644 src/main/java/eu/hbp/mip/configuration/KeycloakConfiguration.java

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index e3a624a13..c05c497c1 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -30,11 +30,11 @@ hbp:
     clientSecret: {{ .Env.CLIENT_SECRET }}
     accessTokenUri: {{ default .Env.TOKEN_URI "https://services.humanbrainproject.eu/oidc/token" }}
     userAuthorizationUri: {{ default .Env.AUTH_URI "https://services.humanbrainproject.eu/oidc/authorize" }}
-    tokenName: oauth_token
+    tokenName: access_token
     authenticationScheme: query
     clientAuthenticationScheme: form
     useCurrentUri: false
-    preEstablishedRedirectUri: {{ default .Env.FRONTEND_LOGIN_URL "http://frontend/services/login/hbp" }}
+    preEstablishedRedirectUri: {{ default .Env.FRONTEND_LOGIN_URL "http://localhost:8080/services/login/hbp" }}
   resource:
     userInfoUri: {{ default .Env.USER_INFO_URI "https://services.humanbrainproject.eu/oidc/userinfo" }}
     revokeTokenUri: {{ default .Env.REVOKE_TOKEN_URI "https://services.humanbrainproject.eu/oidc/slo" }}
@@ -52,6 +52,7 @@ logging:
     root: {{ default .Env.LOG_LEVEL "INFO" }}
     org:
       springframework:
+        security: DEBUG
         web: {{ default .Env.LOGGING_LEVEL_WEB "WARN" }}
         web.servlet.handler.BeanNameUrlHandlerMapping: WARN
       hibernate: {{ default .Env.LOGGING_LEVEL_HIBERNATE "WARN" }}
diff --git a/pom.xml b/pom.xml
index d206d2ad2..f0fbbe9dc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -255,12 +255,6 @@
             <artifactId>java-jwt</artifactId>
             <version>3.8.3</version>
         </dependency>
-        <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-spring-boot-starter</artifactId>
-        </dependency>
-
-
     </dependencies>
 
     <build>
diff --git a/src/main/java/eu/hbp/mip/configuration/KeycloakConfiguration.java b/src/main/java/eu/hbp/mip/configuration/KeycloakConfiguration.java
deleted file mode 100644
index 45c598924..000000000
--- a/src/main/java/eu/hbp/mip/configuration/KeycloakConfiguration.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package eu.hbp.mip.configuration;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import org.keycloak.KeycloakSecurityContext;
-
-public class KeycloakConfiguration {
-
-    @Autowired
-    private HttpServletRequest request;
-    public KeycloakSecurityContext getKeycloakSecurityContext() {
-        return (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index ba6a380de..b8259bca6 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -8,6 +8,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
 import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
 import org.springframework.boot.context.embedded.FilterRegistrationBean;
@@ -34,6 +35,10 @@ import org.springframework.security.web.csrf.CsrfTokenRepository;
 import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
 import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.util.WebUtils;
+import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -42,223 +47,217 @@ import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 
 // See https://spring.io/guides/tutorials/spring-boot-oauth2/ for reference about configuring OAuth2 login
 // also http://cscarioni.blogspot.ch/2013/04/pro-spring-security-and-oauth-2.html
 
-/**
- * Configuration for security.
- */
-@KeycloakConfiguration
-public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
-    @Autowired
-    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
-        auth.authenticationProvider(keycloakAuthenticationProvider());
-    }
+@Configuration
+@EnableOAuth2Client
+public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
-    /**
-     * Defines the session authentication strategy.
-     */
-    @Bean
-    @Override
-    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
-        return new NullAuthenticatedSessionStrategy();
-    }
+   private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
 
-    @Override
-    protected void configure(HttpSecurity http) throws Exception
-    {
-        super.configure(http);
-        http
-                .authorizeRequests()
-                .antMatchers("/user*").authenticated()
-                .antMatchers("/public1*").hasAuthority("public13")
-                .antMatchers("/public2*").hasAuthority("public2")
-                .antMatchers("/public3*").hasAuthority("public3")
-                .antMatchers("/admin*").authenticated()
-                .anyRequest().permitAll()
-                .and()
-                .logout()
-                .addLogoutHandler(keycloakLogoutHandler())//.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
-                .logoutUrl("/logout").permitAll()
-                .logoutSuccessUrl("/");
-//        .anyRequest().permitAll().and().logout().addLogoutHandler(new KeycloakLogoutHandler(new RestTemplate())).logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
-        ;
-    }
+   @Autowired
+   private OAuth2ClientContext oauth2ClientContext;
 
-}
+   /**
+    * Enable HBP collab authentication (1) or disable it (0). Default is 1
+    */
+   @Value("#{'${hbp.authentication.enabled:1}'}")
+   private boolean authentication;
+
+   /**
+    * Absolute URL to redirect to when login is required
+    */
+   @Value("#{'${frontend.loginUrl:/login/hbp}'}")
+   private String loginUrl;
+
+   /**
+    * Absolute URL to redirect to after successful login
+    */
+   @Value("#{'${frontend.redirectAfterLoginUrl:http://frontend/home}'}")
+   private String frontendRedirectAfterLogin;
+
+   /**
+    * Absolute URL to redirect to after logout has occurred
+    */
+   @Value("#{'${frontend.redirectAfterLogoutUrl:/login/hbp}'}")
+   private String redirectAfterLogoutUrl;
+
+   /**
+    * URL to revoke auth token
+    */
+   @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
+   private String revokeTokenURI;
 
-//@Configuration
-//@EnableOAuth2Client
-//public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
-//
-//    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
-//
 //    @Autowired
-//    private OAuth2ClientContext oauth2ClientContext;
-//
-//    /**
-//     * Enable HBP collab authentication (1) or disable it (0). Default is 1
-//     */
-//    @Value("#{'${hbp.authentication.enabled:1}'}")
-//    private boolean authentication;
-//
-//    /**
-//     * Absolute URL to redirect to when login is required
-//     */
-//    @Value("#{'${frontend.loginUrl:/login/hbp}'}")
-//    private String loginUrl;
-//
-//    /**
-//     * Absolute URL to redirect to after successful login
-//     */
-//    @Value("#{'${frontend.redirectAfterLoginUrl:http://frontend/home}'}")
-//    private String frontendRedirectAfterLogin;
-//
-//    /**
-//     * Absolute URL to redirect to after logout has occurred
-//     */
-//    @Value("#{'${frontend.redirectAfterLogoutUrl:/login/hbp}'}")
-//    private String redirectAfterLogoutUrl;
-//
-//    /**
-//     * URL to revoke auth token
-//     */
-//    @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
-//    private String revokeTokenURI;
-//
-////    @Autowired
-////    private HttpServletRequest request;
-//
-//    @Override
-//    protected void configure(HttpSecurity http) throws Exception {
-//        // @formatter:off
-//        http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
-//
-//        if (authentication) {
+//    private HttpServletRequest request;
+
+   @Override
+   protected void configure(HttpSecurity http) throws Exception {
+       // @formatter:off
+       http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
+
+       if (authentication) {
+           http.antMatcher("/**")
+                   .authorizeRequests()
+                   .antMatchers(
+                           "/", "/login/**", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs", "/swagger-ui.html", "/swagger-resources/**"
+                   )
+				   .permitAll()
+                   .antMatchers("/galaxy*","/galaxy/*").hasRole("Data Manager")
+				   //.anyRequest().authenticated()
+				   .anyRequest().hasRole("Researcher")
+                   .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
+                   .and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
+                   .and().logout().permitAll()
+                   .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
+                   .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
+                   .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
+       }
+       else {
+           //keycloak
+           //KeycloakConfiguration.getKeycloakSecurityContext();
 //            http.antMatcher("/**")
 //                    .authorizeRequests()
-//                    .antMatchers(
-//                            "/", "/login/**", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs", "/swagger-ui.html", "/swagger-resources/**"
-//                    ).permitAll()
-//                    .anyRequest().authenticated()
-//                    .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
-//                    .and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
-//                    .and().logout().permitAll()
-//                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
-//                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
-//                    .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
-//        }
-//        else {
-//            //keycloak
-//            //KeycloakConfiguration.getKeycloakSecurityContext();
-////            http.antMatcher("/**")
-////                    .authorizeRequests()
-////                    .antMatchers("/**").permitAll().and().csrf().disable();
-//        }
-//    }
-//
-//    private Filter ssoFilter() {
-//        OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
-//        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
-//        hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
-//        hbpFilter.setRestTemplate(hbpTemplate);
-//        hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId()));
-//        return hbpFilter;
-//    }
-//
-//    @Bean
-//    public FilterRegistrationBean oauth2ClientFilterRegistration(
-//            OAuth2ClientContextFilter filter) {
-//        FilterRegistrationBean registration = new FilterRegistrationBean();
-//        registration.setFilter(filter);
-//        registration.setOrder(-100);
-//        return registration;
-//    }
-//
-//    @Bean(name="hbp")
-//    @ConfigurationProperties("hbp.client")
-//    public OAuth2ProtectedResourceDetails hbp() {
-//        return new AuthorizationCodeResourceDetails();
-//    }
-//
-//    @Bean(name="hbpResource")
-//    @ConfigurationProperties("hbp.resource")
-//    public ResourceServerProperties hbpResource() {
-//        return new ResourceServerProperties();
-//    }
-//
-//    public boolean isAuthentication() {
-//        return authentication;
-//    }
-//
-//    public String getFrontendRedirectAfterLogin() {
-//        return frontendRedirectAfterLogin;
-//    }
-//
-//    private Filter csrfHeaderFilter() {
-//        return new OncePerRequestFilter() {
-//            @Override
-//            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
-//                                            FilterChain filterChain) throws ServletException, IOException {
-//                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
-//                if (csrf != null) {
-//                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
-//                    String token = csrf.getToken();
-//                    if (cookie == null || token != null && !token.equals(cookie.getValue())) {
-//                        cookie = new Cookie("XSRF-TOKEN", token);
-//                        cookie.setPath("/");
-//                        response.addCookie(cookie);
-//                    }
-//                }
-//                filterChain.doFilter(request, response);
-//            }
-//        };
-//    }
-//
-//    private CsrfTokenRepository csrfTokenRepository() {
-//        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
-//        repository.setHeaderName("X-XSRF-TOKEN");
-//        return repository;
-//    }
-//
-//    private class CustomLogoutHandler implements LogoutHandler {
-//        @Override
-//        public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
-//
-//            // Hackish way of accessing to this information...
-//            final UserInfo userInfo = (UserInfo) httpServletRequest.getSession().getAttribute("userInfo");
-//            if (userInfo != null) {
-//                userInfo.setFakeAuth(false);
-//            }
-//
-//            if (oauth2ClientContext == null || oauth2ClientContext.getAccessToken() == null)
-//            {
-//                return;
-//            }
-//
-//            String idToken = oauth2ClientContext.getAccessToken().getAdditionalInformation().get("id_token").toString();
-//
-//            StringBuilder query = new StringBuilder();
-//            query.append("{");
-//            query.append("\"token\":");
-//            query.append("\"").append(idToken).append("\"");
-//            query.append("}");
-//
-//            try {
-//                int responseCode = HTTPUtil.sendPost(revokeTokenURI, query.toString(), new StringBuilder());
-//                if (responseCode != 200)
-//                {
-//                    LOGGER.warn("Cannot send request to OIDC server for revocation ! ");
-//                }
-//                else{
-//                    LOGGER.info("Should be logged out");
-//                }
-//            } catch (IOException e) {
-//                LOGGER.warn("Cannot notify logout to OIDC server !");
-//                LOGGER.trace("Cannot notify logout", e);
-//            }
-//
-//        }
-//    }
-//}
+//                    .antMatchers("/**").permitAll().and().csrf().disable();
+       }
+   }
+
+   private Filter ssoFilter() {
+       OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
+       OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
+       hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
+       hbpFilter.setRestTemplate(hbpTemplate);
+       hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId()));
+       return hbpFilter;
+   }
+
+   @Bean
+   public FilterRegistrationBean oauth2ClientFilterRegistration(
+           OAuth2ClientContextFilter filter) {
+       FilterRegistrationBean registration = new FilterRegistrationBean();
+       registration.setFilter(filter);
+       registration.setOrder(-100);
+       return registration;
+   }
+
+   @Bean(name="hbp")
+   @ConfigurationProperties("hbp.client")
+   public BaseOAuth2ProtectedResourceDetails hbp() {
+       return new AuthorizationCodeResourceDetails();
+   }
+
+   @Bean(name="hbpResource")
+   @ConfigurationProperties("hbp.resource")
+   public ResourceServerProperties hbpResource() {
+       return new ResourceServerProperties();
+   }
+
+   public boolean isAuthentication() {
+       return authentication;
+   }
+
+   public String getFrontendRedirectAfterLogin() {
+       return frontendRedirectAfterLogin;
+   }
+
+   private Filter csrfHeaderFilter() {
+       return new OncePerRequestFilter() {
+           @Override
+           protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
+                                           FilterChain filterChain) throws ServletException, IOException {
+               CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
+               if (csrf != null) {
+                   Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
+                   String token = csrf.getToken();
+                   if (cookie == null || token != null && !token.equals(cookie.getValue())) {
+                       cookie = new Cookie("XSRF-TOKEN", token);
+                       cookie.setPath("/");
+                       response.addCookie(cookie);
+                   }
+               }
+               filterChain.doFilter(request, response);
+           }
+       };
+   }
+
+   private CsrfTokenRepository csrfTokenRepository() {
+       HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
+       repository.setHeaderName("X-XSRF-TOKEN");
+       return repository;
+   }
+
+   private class CustomLogoutHandler implements LogoutHandler {
+       @Override
+       public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
+
+           // Hackish way of accessing to this information...
+           final UserInfo userInfo = (UserInfo) httpServletRequest.getSession().getAttribute("userInfo");
+           if (userInfo != null) {
+               userInfo.setFakeAuth(false);
+           }
+
+           if (oauth2ClientContext == null || oauth2ClientContext.getAccessToken() == null)
+           {
+               return;
+           }
+
+           String idToken = oauth2ClientContext.getAccessToken().getAdditionalInformation().get("id_token").toString();
+
+           StringBuilder query = new StringBuilder();
+           query.append("{");
+           query.append("\"token\":");
+           query.append("\"").append(idToken).append("\"");
+           query.append("}");
+
+           try {
+               int responseCode = HTTPUtil.sendPost(revokeTokenURI, query.toString(), new StringBuilder());
+               if (responseCode != 200)
+               {
+                   LOGGER.warn("Cannot send request to OIDC server for revocation ! ");
+               }
+               else{
+                   LOGGER.info("Should be logged out");
+               }
+           } catch (IOException e) {
+               LOGGER.warn("Cannot notify logout to OIDC server !");
+               LOGGER.trace("Cannot notify logout", e);
+           }
+
+       }
+   }
+   
+    @Bean
+    public AuthoritiesExtractor keycloakAuthoritiesExtractor() {
+        return new KeycloakAuthoritiesExtractor();
+    }
+
+
+    public class KeycloakAuthoritiesExtractor
+            implements AuthoritiesExtractor {
+
+        @Override
+        public List<GrantedAuthority> extractAuthorities
+                (Map<String, Object> map) {
+            return AuthorityUtils
+                    .commaSeparatedStringToAuthorityList(asAuthorities(map));
+        }
+
+        private String asAuthorities(Map<String, Object> map) {
+            List<String> authorities = new ArrayList<>();
+//            authorities.add("BAELDUNG_USER");
+            List<LinkedHashMap<String, String>> authz;
+            authz = (List<LinkedHashMap<String, String>>) map.get("authorities");
+            for (LinkedHashMap<String, String> entry : authz) {
+                authorities.add(entry.get("authority"));
+            }
+            return String.join(",", authorities);
+        }
+    }
+   
+}
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index cfddbd334..08c6f0410 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -17,6 +17,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.security.access.prepost.PreAuthorize;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletResponse;
@@ -102,6 +103,7 @@ public class SecurityApi {
      */
 
     @RequestMapping(path = "/galaxy", method = RequestMethod.GET, produces = "application/json")
+	@PreAuthorize("hasRole('Data Manager')")
     @ResponseStatus(value = HttpStatus.OK)
     public ResponseEntity getGalaxyConfiguration(){
         String stringEncoded = Base64.getEncoder().encodeToString((galaxyUsername + ":" + galaxyPassword).getBytes());
-- 
GitLab


From ca65f167f2039c44e1e66ef824d3481e80484b3f Mon Sep 17 00:00:00 2001
From: jerrypan44 <jerrypan44@gmail.com>
Date: Fri, 29 Nov 2019 14:48:35 +0000
Subject: [PATCH 7/9] adding logging support for API calls

---
 pom.xml                                       | 36 +--------
 .../configuration/SecurityConfiguration.java  |  3 +-
 .../eu/hbp/mip/controllers/ArticlesApi.java   | 25 +++---
 .../eu/hbp/mip/controllers/ExperimentApi.java | 81 +++++++++++--------
 .../java/eu/hbp/mip/controllers/FilesAPI.java |  8 +-
 .../java/eu/hbp/mip/controllers/JWTApi.java   |  5 +-
 .../eu/hbp/mip/controllers/MethodsApi.java    |  8 +-
 .../eu/hbp/mip/controllers/MiningApi.java     |  6 +-
 .../eu/hbp/mip/controllers/ModelsApi.java     | 18 ++---
 .../hbp/mip/controllers/PathologiesApi.java   |  3 +
 .../eu/hbp/mip/controllers/SecurityApi.java   | 14 ++--
 .../java/eu/hbp/mip/controllers/StatsApi.java |  7 +-
 .../java/eu/hbp/mip/controllers/UsersApi.java |  5 +-
 .../eu/hbp/mip/utils/UserActionLogging.java   | 23 ++++++
 src/main/resources/logback.xml                | 14 ++++
 15 files changed, 136 insertions(+), 120 deletions(-)
 create mode 100644 src/main/java/eu/hbp/mip/utils/UserActionLogging.java
 create mode 100644 src/main/resources/logback.xml

diff --git a/pom.xml b/pom.xml
index f0fbbe9dc..dfec021ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,30 +66,15 @@
     </repositories>
 
     <dependencies>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-log4j2</artifactId>
-        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.springframework.boot</groupId>
-                    <artifactId>spring-boot-starter-logging</artifactId>
-                </exclusion>
-            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
             <version>${spring-boot-starter-actuator.version}</version>
-             <exclusions>
-                <exclusion>
-                    <groupId>org.springframework.boot</groupId>
-                    <artifactId>spring-boot-starter-logging</artifactId>
-                </exclusion>
-            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.springframework.data</groupId>
@@ -99,22 +84,11 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
-             <exclusions>
-                <exclusion>
-                    <groupId>org.springframework.boot</groupId>
-                    <artifactId>spring-boot-starter-logging</artifactId>
-                </exclusion>
-            </exclusions>
+
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
-             <exclusions>
-                <exclusion>
-                    <groupId>org.springframework.boot</groupId>
-                    <artifactId>spring-boot-starter-logging</artifactId>
-                </exclusion>
-            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.springframework.security.oauth</groupId>
@@ -146,12 +120,6 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
-             <exclusions>
-                <exclusion>
-                    <groupId>org.springframework.boot</groupId>
-                    <artifactId>spring-boot-starter-logging</artifactId>
-                </exclusion>
-            </exclusions>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index b8259bca6..9310be3de 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -4,6 +4,7 @@ import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.utils.CORSFilter;
 import eu.hbp.mip.utils.CustomLoginUrlAuthenticationEntryPoint;
 import eu.hbp.mip.utils.HTTPUtil;
+import eu.hbp.mip.utils.UserActionLogging;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -131,7 +132,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    private Filter ssoFilter() {
        OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/hbp");
        OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext);
-       hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
+	   hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin));
        hbpFilter.setRestTemplate(hbpTemplate);
        hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId()));
        return hbpFilter;
diff --git a/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java b/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java
index 3b567b102..963b18157 100644
--- a/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ArticlesApi.java
@@ -10,6 +10,7 @@ import eu.hbp.mip.model.Article;
 import eu.hbp.mip.model.User;
 import eu.hbp.mip.model.UserInfo;
 import eu.hbp.mip.repositories.ArticleRepository;
+import eu.hbp.mip.utils.UserActionLogging;
 import io.swagger.annotations.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,8 +31,6 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/articles", description = "the articles API")
 public class ArticlesApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(ArticlesApi.class);
-
     @Autowired
     private UserInfo userInfo;
 
@@ -44,8 +43,6 @@ public class ArticlesApi {
             @ApiParam(value = "Only ask own articles") @RequestParam(value = "own", required = false) Boolean own,
             @ApiParam(value = "Only ask results matching status", allowableValues = "draft, published") @RequestParam(value = "status", required = false) String status
     ) {
-        LOGGER.info("Get articles");
-
         User user = userInfo.getUser();
         Iterable<Article> articles;
 
@@ -69,7 +66,8 @@ public class ArticlesApi {
                 }
             }
         }
-
+		UserActionLogging.LogAction("Get articles", "id : Get All articles");
+        
         return ResponseEntity.ok(articles);
     }
 
@@ -80,8 +78,7 @@ public class ArticlesApi {
     public ResponseEntity<Void> addAnArticle(
             @RequestBody @ApiParam(value = "Article to create", required = true) @Valid Article article
     ) {
-        LOGGER.info("Create an article");
-
+        
         User user = userInfo.getUser();
 
         article.setCreatedAt(new Date());
@@ -111,7 +108,7 @@ public class ArticlesApi {
             slug = new Slugify().slugify(article.getTitle());
         } catch (IOException e) {
             slug = "";
-            LOGGER.trace("Cannot slugify title", e);
+            //LOGGER.trace("Cannot slugify title", e);
         }
 
         boolean alreadyExists = true;
@@ -130,8 +127,7 @@ public class ArticlesApi {
         }
         articleRepository.save(article);
 
-        LOGGER.info("Article saved");
-
+		UserActionLogging.LogAction("Created article", "id : " + article.getSlug());
         return new ResponseEntity<>(HttpStatus.CREATED);
     }
 
@@ -141,7 +137,7 @@ public class ArticlesApi {
     public ResponseEntity<Article> getAnArticle(
             @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug
     ) {
-        LOGGER.info("Get an article");
+		UserActionLogging.LogAction("Getting an article", "id : " + slug);
 
         User user = userInfo.getUser();
         Article article;
@@ -149,7 +145,7 @@ public class ArticlesApi {
 
         if(article == null)
         {
-            LOGGER.warn("Cannot find article : " + slug);
+            //LOGGER.warn("Cannot find article : " + slug);
             return ResponseEntity.badRequest().body(null);
         }
 
@@ -169,7 +165,7 @@ public class ArticlesApi {
             @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug,
             @RequestBody @ApiParam(value = "Article to update", required = true) @Valid Article article
     ) {
-        LOGGER.info("Update an article");
+        UserActionLogging.LogAction("Update an article", "id : " + slug);
 
         User user = userInfo.getUser();
 
@@ -201,8 +197,7 @@ public class ArticlesApi {
 
         articleRepository.save(article);
 
-        LOGGER.info("Article updated");
-
+        
         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
index 9f4fee480..deef20f75 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentApi.java
@@ -20,6 +20,7 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import eu.hbp.mip.utils.JWTUtil;
+import eu.hbp.mip.utils.UserActionLogging;
 
 import java.io.IOException;
 import java.util.*;
@@ -33,7 +34,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/experiments", description = "the experiments API")
 public class ExperimentApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(ExperimentApi.class);
+    //private static final Logger LOGGER = LoggerFactory.getLogger(ExperimentApi.class);
 
     private static final Gson gson = new Gson();
 
@@ -61,7 +62,7 @@ public class ExperimentApi {
     @ApiOperation(value = "Create an experiment on Exareme", response = Experiment.class)
     @RequestMapping(value = "/exareme", method = RequestMethod.POST)
     public ResponseEntity<String> runExaremeExperiment(@RequestBody ExperimentQuery expQuery) {
-        LOGGER.info("send ExaremeExperiment");
+        //LOGGER.info("send ExaremeExperiment");
 
         Experiment experiment = saveExperiment(expQuery);
 
@@ -87,23 +88,24 @@ public class ExperimentApi {
                 experiment.setHasError(code >= 400);
                 experiment.setHasServerError(code >= 500);
             } catch (IOException e) {
-                LOGGER.trace("Invalid UUID", e);
-                LOGGER.warn("Exareme experiment failed to run properly !");
+                //LOGGER.trace("Invalid UUID", e);
+                //LOGGER.warn("Exareme experiment failed to run properly !");
                 experiment.setHasError(true);
                 experiment.setHasServerError(true);
                 experiment.setResult(e.getMessage());
             }
             finishExperiment(experiment);
         }).start();
-
+		
+		UserActionLogging.LogAction("create ExaremeExperiment", "no info");
+		
         return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Create a workflow", response = Experiment.class)
     @RequestMapping(value = "/workflow", method = RequestMethod.POST)
     public ResponseEntity<String> runWorkflow(@RequestBody ExperimentQuery expQuery) {
-        LOGGER.info("send Workflow");
-
+        
         Experiment experiment = saveExperiment(expQuery);
 
         String algoCode = expQuery.getAlgorithms().get(0).getCode();
@@ -132,7 +134,7 @@ public class ExperimentApi {
                 experiment.setHasError(code >= 400);
                 experiment.setHasServerError(code >= 500);
             } catch (IOException e) {
-                LOGGER.trace("Invalid UUID", e);
+                //LOGGER.trace("Invalid UUID", e);
                 experiment.setHasError(true);
                 experiment.setHasServerError(true);
                 experiment.setResult(e.getMessage());
@@ -140,6 +142,8 @@ public class ExperimentApi {
             finishExperiment(experiment);
         }).start();
 
+		UserActionLogging.LogAction("create workflow", "no info");
+		
         return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
     }
 
@@ -147,15 +151,14 @@ public class ExperimentApi {
     @RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
     public ResponseEntity<String> getExperiment(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        LOGGER.info("Get an experiment");
 
         Experiment experiment;
         UUID experimentUuid;
         try {
             experimentUuid = UUID.fromString(uuid);
         } catch (IllegalArgumentException iae) {
-            LOGGER.trace("Invalid UUID", iae);
-            LOGGER.warn("An invalid Experiment UUID was received ! " + uuid);
+            //LOGGER.trace("Invalid UUID", iae);
+            //LOGGER.warn("An invalid Experiment UUID was received ! " + uuid);
             return ResponseEntity.badRequest().body("Invalid Experiment UUID");
         }
 
@@ -164,7 +167,9 @@ public class ExperimentApi {
         if (experiment == null) {
             return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND);
         }
-
+		
+		UserActionLogging.LogAction("Get an experiment ", " uuid : "+ uuid);
+		
         return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
     }
 
@@ -172,8 +177,9 @@ public class ExperimentApi {
     @RequestMapping(value = "/workflow/status/{historyId}", method = RequestMethod.GET)
     public ResponseEntity<String> getWorkflowStatus(
             @ApiParam(value = "historyId", required = true) @PathVariable("historyId") String historyId) {
-        LOGGER.info("Get a workflow status");
-
+       
+		UserActionLogging.LogAction("Get a workflow status", " historyId : "+ historyId);
+		
         String url = workflowUrl + "/getWorkflowStatus/" + historyId;
         try {
             User user = userInfo.getUser();
@@ -186,6 +192,7 @@ public class ExperimentApi {
         } catch (IOException e) {
             return ResponseEntity.status(500).body(e.getMessage());
         }
+		
     }
 
     // TODO: factorize workflow results
@@ -193,8 +200,8 @@ public class ExperimentApi {
     @RequestMapping(value = "/workflow/results/{historyId}", method = RequestMethod.GET)
     public ResponseEntity<String> getWorkflowResults(
             @ApiParam(value = "historyId", required = true) @PathVariable("historyId") String historyId) {
-        LOGGER.info("Get a workflow results");
-
+        UserActionLogging.LogAction("Get workflow results", " historyId : "+ historyId);
+		
         String url = workflowUrl + "/getWorkflowResults/" + historyId;
         try {
             StringBuilder response = new StringBuilder();
@@ -214,8 +221,9 @@ public class ExperimentApi {
     public ResponseEntity<String> getWorkflowResultBody(
             @ApiParam(value = "historyId", required = true) @PathVariable("historyId") String historyId,
             @ApiParam(value = "resultId", required = true) @PathVariable("resultId") String resultId) {
-        LOGGER.info("Get a workflow result content");
 
+		UserActionLogging.LogAction("Get workflow result content", " historyId : "+ historyId + " resultId : "+ resultId);
+		
         String url = workflowUrl + "/getWorkflowResultsBody/" + historyId + "/contents/" + resultId;
         try {
             StringBuilder response = new StringBuilder();
@@ -235,7 +243,7 @@ public class ExperimentApi {
     public ResponseEntity<String> getWorkflowResultsDetails(
             @ApiParam(value = "historyId", required = true) @PathVariable("historyId") String historyId,
             @ApiParam(value = "resultId", required = true) @PathVariable("resultId") String resultId) {
-        LOGGER.info("Get a workflow result content");
+		UserActionLogging.LogAction("Get workflow result details", " historyId : "+ historyId + " resultId : "+ resultId);
 
         String url = workflowUrl + "/getWorkflowResultsDetails/" + historyId + "/contents/" + resultId;
         try {
@@ -255,7 +263,8 @@ public class ExperimentApi {
     @RequestMapping(value = "/{uuid}/markAsViewed", method = RequestMethod.GET)
     public ResponseEntity<String> markExperimentAsViewed(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        LOGGER.info("Mark an experiment as viewed");
+
+		UserActionLogging.LogAction("Mark an experiment as viewed", " uuid : "+ uuid);
 
         Experiment experiment;
         UUID experimentUuid;
@@ -263,8 +272,8 @@ public class ExperimentApi {
         try {
             experimentUuid = UUID.fromString(uuid);
         } catch (IllegalArgumentException iae) {
-            LOGGER.trace("Invalid UUID", iae);
-            LOGGER.warn("An invalid Experiment UUID was received !");
+            //LOGGER.trace("Invalid UUID", iae);
+            //LOGGER.warn("An invalid Experiment UUID was received !");
             return ResponseEntity.badRequest().body("Invalid Experiment UUID");
         }
 
@@ -274,7 +283,7 @@ public class ExperimentApi {
         experiment.setResultsViewed(true);
         experimentRepository.save(experiment);
 
-        LOGGER.info("Experiment updated (marked as viewed)");
+		UserActionLogging.LogAction("Experiment updated (marked as viewed)", " ");
 
         return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
     }
@@ -283,8 +292,9 @@ public class ExperimentApi {
     @RequestMapping(value = "/{uuid}/markAsShared", method = RequestMethod.GET)
     public ResponseEntity<String> markExperimentAsShared(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        LOGGER.info("Mark an experiment as shared");
 
+		UserActionLogging.LogAction("Mark an experiment as shared", " uuid : "+ uuid);
+		
         return doMarkExperimentAsShared(uuid, true);
     }
 
@@ -292,8 +302,8 @@ public class ExperimentApi {
     @RequestMapping(value = "/{uuid}/markAsUnshared", method = RequestMethod.GET)
     public ResponseEntity<String> markExperimentAsUnshared(
             @ApiParam(value = "uuid", required = true) @PathVariable("uuid") String uuid) {
-        LOGGER.info("Mark an experiment as unshared");
-
+		UserActionLogging.LogAction("Mark an experiment as unshared", " uuid : "+ uuid);
+		
         return doMarkExperimentAsShared(uuid, false);
     }
 
@@ -301,8 +311,9 @@ public class ExperimentApi {
     @RequestMapping(method = RequestMethod.GET, params = { "maxResultCount" })
     public ResponseEntity<String> listExperiments(
             @ApiParam(value = "maxResultCount") @RequestParam int maxResultCount) {
-        LOGGER.info("List experiments");
 
+		UserActionLogging.LogAction("List experiments", " maxResultCount : "+ maxResultCount);
+		
         return doListExperiments(false, null);
     }
 
@@ -310,7 +321,8 @@ public class ExperimentApi {
     @RequestMapping(method = RequestMethod.GET, params = { "slug", "maxResultCount" })
     public ResponseEntity<String> listExperiments(@ApiParam(value = "slug") @RequestParam("slug") String modelSlug,
             @ApiParam(value = "maxResultCount") @RequestParam("maxResultCount") int maxResultCount) {
-        LOGGER.info("List experiments");
+
+		UserActionLogging.LogAction("List experiments", " modelSlug : "+ modelSlug);
 
         if (maxResultCount <= 0 && (modelSlug == null || "".equals(modelSlug))) {
             return new ResponseEntity<>("You must provide at least a slug or a limit of result",
@@ -323,7 +335,7 @@ public class ExperimentApi {
     @ApiOperation(value = "list my experiments", response = Experiment.class, responseContainer = "List")
     @RequestMapping(method = RequestMethod.GET, params = { "mine" })
     public ResponseEntity<String> listMyExperiments(@ApiParam(value = "mine") @RequestParam("mine") boolean mine) {
-        LOGGER.info("List my experiments");
+        UserActionLogging.LogAction("List my experiments", " mine : "+ mine);
 
         return doListExperiments(true, null);
     }
@@ -361,8 +373,8 @@ public class ExperimentApi {
         try {
             experimentUuid = UUID.fromString(uuid);
         } catch (IllegalArgumentException iae) {
-            LOGGER.trace("Invalid UUID", iae);
-            LOGGER.warn("An invalid Experiment UUID was received !");
+            //LOGGER.trace("Invalid UUID", iae);
+            //LOGGER.warn("An invalid Experiment UUID was received !");
             return ResponseEntity.badRequest().body("Invalid Experiment UUID");
         }
 
@@ -373,8 +385,8 @@ public class ExperimentApi {
 
         experiment.setShared(shared);
         experimentRepository.save(experiment);
-
-        LOGGER.info("Experiment updated (marked as shared)");
+		
+		UserActionLogging.LogAction("Experiment updated (marked as shared)", "");
 
         return new ResponseEntity<>(gsonOnlyExposed.toJson(experiment.jsonify()), HttpStatus.OK);
     }
@@ -383,7 +395,7 @@ public class ExperimentApi {
         experiment.setFinished(new Date());
         experimentRepository.save(experiment);
 
-        LOGGER.info("Experiment updated (finished)");
+        UserActionLogging.LogAction("Experiment updated (finished)","");
     }
 
     private HashMap<String, String> makeObject(String name, String value) {
@@ -395,7 +407,6 @@ public class ExperimentApi {
     }
 
     private Experiment saveExperiment(ExperimentQuery expQuery) {
-        LOGGER.info("saveExperiment");
 
         Experiment experiment = new Experiment();
         experiment.setUuid(UUID.randomUUID());
@@ -408,7 +419,7 @@ public class ExperimentApi {
         experiment.setModel(modelRepository.findOne(expQuery.getModel()));
         experimentRepository.save(experiment);
 
-        LOGGER.info("Experiment saved");
+        UserActionLogging.LogAction("Saved an experiment", " id : "+experiment.getUuid());
 
         return experiment;
     }
diff --git a/src/main/java/eu/hbp/mip/controllers/FilesAPI.java b/src/main/java/eu/hbp/mip/controllers/FilesAPI.java
index d79717062..5acdb38ca 100644
--- a/src/main/java/eu/hbp/mip/controllers/FilesAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/FilesAPI.java
@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
+import eu.hbp.mip.utils.UserActionLogging;
 
 import java.time.LocalDateTime;
 
@@ -26,8 +27,7 @@ import java.time.LocalDateTime;
 @Api(value = "/protected", description = "the protected files API")
 public class FilesAPI {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(FilesAPI.class);
-
+    
     @Autowired
     private UserInfo userInfo;
 
@@ -36,12 +36,12 @@ public class FilesAPI {
     public ResponseEntity<Void> getProtectedFile(
             @ApiParam(value = "filename", required = true) @PathVariable("filename") String filename
     ) {
-        LOGGER.info("Get protected file");
+        UserActionLogging.LogAction("Get protected file", " filename : " + filename);
 
         String filepath = "/protected/" + filename;
         String user = userInfo.getUser().getUsername();
         String time = LocalDateTime.now().toString();
-        LOGGER.info("User " + user + " downloaded " + filepath + " at "+ time);
+        UserActionLogging.LogAction("User " + user + " downloaded " + filepath, "");
 
         HttpHeaders headers = new HttpHeaders();
         headers.add("X-Accel-Redirect", filepath);
diff --git a/src/main/java/eu/hbp/mip/controllers/JWTApi.java b/src/main/java/eu/hbp/mip/controllers/JWTApi.java
index a3d939bbb..a1cb6afd5 100644
--- a/src/main/java/eu/hbp/mip/controllers/JWTApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/JWTApi.java
@@ -13,14 +13,13 @@ import org.springframework.web.bind.annotation.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import eu.hbp.mip.utils.JWTUtil;
+import eu.hbp.mip.utils.UserActionLogging;
 
 @RestController
 @RequestMapping(value = "/jwt", produces = { TEXT_PLAIN_VALUE })
 @Api(value = "/jwt", description = "the jwt API")
 public class JWTApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(JWTApi.class);
-
     @Autowired
     private UserInfo userInfo;
 
@@ -31,7 +30,7 @@ public class JWTApi {
     @RequestMapping(method = RequestMethod.POST)
     public ResponseEntity<String> createJWT() {
 
-        LOGGER.info("Create a JSON Web Token");
+        UserActionLogging.LogAction("Create a JSON Web Token", "");
 
         User user = userInfo.getUser();
         String token = JWTUtil.getJWT(jwtSecret, user.getEmail());
diff --git a/src/main/java/eu/hbp/mip/controllers/MethodsApi.java b/src/main/java/eu/hbp/mip/controllers/MethodsApi.java
index fe7e8cd45..f88f67951 100644
--- a/src/main/java/eu/hbp/mip/controllers/MethodsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/MethodsApi.java
@@ -15,14 +15,14 @@ import java.io.IOException;
 import eu.hbp.mip.utils.JWTUtil;
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 import org.springframework.beans.factory.annotation.Autowired;
+import eu.hbp.mip.utils.UserActionLogging;
 
 @RestController
 @RequestMapping(value = "/methods", produces = { APPLICATION_JSON_VALUE })
 @Api(value = "/methods", description = "the methods API")
 public class MethodsApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(MethodsApi.class);
-
+    
     private static final Gson gson = new Gson();
 
     @Value("#{'${services.exareme.algorithmsUrl:http://localhost:9090/mining/algorithms.json}'}")
@@ -40,7 +40,7 @@ public class MethodsApi {
     @ApiOperation(value = "List Exareme algorithms and validations", response = String.class)
     @RequestMapping(value = "/exareme", method = RequestMethod.GET)
     public ResponseEntity<Object> getExaremeAlgorithms() {
-        LOGGER.info("List Exareme algorithms and validations");
+        UserActionLogging.LogAction("List Exareme algorithms and validations", "");
 
         try {
             StringBuilder response = new StringBuilder();
@@ -57,7 +57,7 @@ public class MethodsApi {
     @ApiOperation(value = "List Galaxy workflows", response = String.class)
     @RequestMapping(value = "/workflows", method = RequestMethod.GET)
     public ResponseEntity<Object> getWorkflows() {
-        LOGGER.info("List Galaxy workflows");
+        UserActionLogging.LogAction("List Galaxy workflows", "");
 
         try {
             User user = userInfo.getUser();
diff --git a/src/main/java/eu/hbp/mip/controllers/MiningApi.java b/src/main/java/eu/hbp/mip/controllers/MiningApi.java
index c289856a0..919fb5a2c 100644
--- a/src/main/java/eu/hbp/mip/controllers/MiningApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/MiningApi.java
@@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
+import eu.hbp.mip.utils.UserActionLogging;
 
 import java.util.*;
 import java.io.IOException;
@@ -34,7 +35,6 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/mining", description = "the mining API")
 public class MiningApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(MiningApi.class);
     private static final Gson gson = new Gson();
 
     @Autowired
@@ -46,7 +46,7 @@ public class MiningApi {
     @ApiOperation(value = "Create an histogram on Exareme", response = String.class)
     @RequestMapping(value = "/exareme", method = RequestMethod.POST)
     public ResponseEntity runExaremeMining(@RequestBody List<HashMap<String, String>> queryList) {
-        LOGGER.info("Run an histogram");
+        UserActionLogging.LogAction("Run an histogram", "");
 
         String query = gson.toJson(queryList);
         String url = miningExaremeQueryUrl + "/" + "HISTOGRAMS";
@@ -64,7 +64,7 @@ public class MiningApi {
     @ApiOperation(value = "Create an descriptive statistic on Exareme", response = String.class)
     @RequestMapping(value = "/exareme-stats", method = RequestMethod.POST)
     public ResponseEntity runExaremeDescriptiveStats(@RequestBody List<HashMap<String, String>> queryList) {
-        LOGGER.info("Run descriptive stats");
+        UserActionLogging.LogAction("Run descriptive stats", "");
 
         String query = gson.toJson(queryList);
         String url = miningExaremeQueryUrl + "/" + "DESCRIPTIVE_STATS";
diff --git a/src/main/java/eu/hbp/mip/controllers/ModelsApi.java b/src/main/java/eu/hbp/mip/controllers/ModelsApi.java
index 56bc1ce10..02ee9ac6b 100644
--- a/src/main/java/eu/hbp/mip/controllers/ModelsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/ModelsApi.java
@@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
+import eu.hbp.mip.utils.UserActionLogging;
 
 import java.io.IOException;
 import java.util.*;
@@ -28,7 +29,6 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/models", description = "the models API")
 public class ModelsApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(ModelsApi.class);
 
     @Autowired
     private UserInfo userInfo;
@@ -54,7 +54,7 @@ public class ModelsApi {
             @ApiParam(value = "Only ask own models") @RequestParam(value = "own", required = false) Boolean own,
             @ApiParam(value = "Only ask published models") @RequestParam(value = "valid", required = false) Boolean valid
     )  {
-        LOGGER.info("Get models");
+        UserActionLogging.LogAction("Get models","");
 
         User user = userInfo.getUser();
 
@@ -98,7 +98,7 @@ public class ModelsApi {
             @RequestBody @ApiParam(value = "Model to create", required = true) Model model
     )  {
 
-        LOGGER.info("Create a model");
+        UserActionLogging.LogAction("Create a model","");
 
         User user = userInfo.getUser();
 
@@ -129,7 +129,7 @@ public class ModelsApi {
         }
         modelRepository.save(model);
 
-        LOGGER.info("Model saved (also saved model.config and model.query)");
+        UserActionLogging.LogAction("Model saved (also saved model.config and model.query)"," id : " + model.getSlug());
 
         return ResponseEntity.status(HttpStatus.CREATED).body(model);
     }
@@ -165,7 +165,7 @@ public class ModelsApi {
             slug = new Slugify().slugify(title);
         } catch (IOException e) {
             slug = "";  // Should never happen
-            LOGGER.trace("Cannot slugify title", e);
+            //LOGGER.trace("Cannot slugify title", e);
         }
         return slug;
     }
@@ -192,7 +192,7 @@ public class ModelsApi {
     public ResponseEntity<Model> getAModel(
             @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug
     )  {
-        LOGGER.info("Get a model");
+        UserActionLogging.LogAction("Get a model", " id : " + slug);
 
         User user = userInfo.getUser();
 
@@ -200,7 +200,7 @@ public class ModelsApi {
 
         if(model == null)
         {
-            LOGGER.warn("Cannot find model : " + slug);
+            //LOGGER.warn("Cannot find model : " + slug);
             return ResponseEntity.badRequest().body(null);
         }
 
@@ -224,7 +224,7 @@ public class ModelsApi {
             @ApiParam(value = "slug", required = true) @PathVariable("slug") String slug,
             @RequestBody @ApiParam(value = "Model to update", required = true) Model model
     )  {
-        LOGGER.info("Update a model");
+        UserActionLogging.LogAction("Update a model", " id : "+ slug);
 
         User user = userInfo.getUser();
         Model oldModel = modelRepository.findOne(slug);
@@ -269,7 +269,7 @@ public class ModelsApi {
         datasetRepository.save(model.getDataset());
         modelRepository.save(model);
 
-        LOGGER.info("Model updated (also saved/updated model.config and model.query)");
+        UserActionLogging.LogAction("Model updated (also saved/updated model.config and model.query)", " id : "+ slug);
 
         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
index 59511de85..27f635d32 100644
--- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java
@@ -18,6 +18,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import eu.hbp.mip.utils.UserActionLogging;
 
 import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 
@@ -28,6 +29,8 @@ public class PathologiesApi {
 
     @RequestMapping(name = "/pathologies", method = RequestMethod.GET)
     public String getPathologies() {
+		UserActionLogging.LogAction("load the pathologies", "");
+		
         return loadPathologies();
     }
 
diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
index 08c6f0410..0f93c437e 100644
--- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java
@@ -18,6 +18,7 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.security.access.prepost.PreAuthorize;
+import eu.hbp.mip.utils.UserActionLogging;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletResponse;
@@ -30,8 +31,6 @@ import java.util.Base64;
 @RestController
 public class SecurityApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityApi.class);
-
     private static final Gson gson = new Gson();
 
     @Autowired
@@ -46,7 +45,8 @@ public class SecurityApi {
     @RequestMapping(path = "/user", method = RequestMethod.GET)
     public Object user(Principal principal, HttpServletResponse response) {
         ObjectMapper mapper = new ObjectMapper();
-
+		
+		UserActionLogging.LogAction("get user from /user","");
         try {
             String userJSON = mapper.writeValueAsString(userInfo.getUser());
             Cookie cookie = new Cookie("user", URLEncoder.encode(userJSON, "UTF-8"));
@@ -54,7 +54,7 @@ public class SecurityApi {
             cookie.setPath("/");
             response.addCookie(cookie);
         } catch (JsonProcessingException | UnsupportedEncodingException e) {
-            LOGGER.trace("Cannot read user json", e);
+            //LOGGER.trace("Cannot read user json", e);
         }
 
         if (!securityConfiguration.isAuthentication()) {
@@ -77,6 +77,9 @@ public class SecurityApi {
             user.setAgreeNDA(agreeNDA);
             userRepository.save(user);
         }
+		
+		UserActionLogging.LogAction("user agreeNDA","");
+		
         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
@@ -110,7 +113,8 @@ public class SecurityApi {
         JsonObject object = new JsonObject();
         object.addProperty("authorization", stringEncoded);
         object.addProperty("context", galaxyContext);
-
+		UserActionLogging.LogAction("get galaxy information","");
+		
         return ResponseEntity.ok(gson.toJson(object));
     }
 
diff --git a/src/main/java/eu/hbp/mip/controllers/StatsApi.java b/src/main/java/eu/hbp/mip/controllers/StatsApi.java
index d09c032bc..a92adecde 100644
--- a/src/main/java/eu/hbp/mip/controllers/StatsApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/StatsApi.java
@@ -3,7 +3,7 @@
  */
 
 package eu.hbp.mip.controllers;
-
+import eu.hbp.mip.utils.UserActionLogging;
 import eu.hbp.mip.model.GeneralStats;
 import eu.hbp.mip.repositories.ArticleRepository;
 import eu.hbp.mip.repositories.UserRepository;
@@ -25,8 +25,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/stats", description = "the stats API")
 public class StatsApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(StatsApi.class);
-
+    
     @Autowired
     private UserRepository userRepository;
 
@@ -37,7 +36,7 @@ public class StatsApi {
     @ApiOperation(value = "Get general statistics", response = GeneralStats.class)
     @RequestMapping(method = RequestMethod.GET)
     public ResponseEntity<GeneralStats> getGeneralStatistics()  {
-        LOGGER.info("Get statistics (count on users, articles and variables)");
+        UserActionLogging.LogAction("Get statistics (count on users, articles and variables)","");
 
         GeneralStats stats = new GeneralStats();
 
diff --git a/src/main/java/eu/hbp/mip/controllers/UsersApi.java b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
index 89767017e..ed3104eb8 100644
--- a/src/main/java/eu/hbp/mip/controllers/UsersApi.java
+++ b/src/main/java/eu/hbp/mip/controllers/UsersApi.java
@@ -4,6 +4,7 @@
 
 package eu.hbp.mip.controllers;
 
+import eu.hbp.mip.utils.UserActionLogging;
 import io.swagger.annotations.*;
 import eu.hbp.mip.model.User;
 import eu.hbp.mip.repositories.UserRepository;
@@ -23,8 +24,6 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
 @Api(value = "/users", description = "the users API")
 public class UsersApi {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(UsersApi.class);
-
     @Autowired
     private UserRepository userRepository;
 
@@ -33,7 +32,7 @@ public class UsersApi {
     public ResponseEntity<User> getAUser(
             @ApiParam(value = "username", required = true) @PathVariable("username") String username
     )  {
-        LOGGER.info("Get a user");
+        UserActionLogging.LogAction("Get a user","");
 
         return ResponseEntity.ok(userRepository.findOne(username));
     }
diff --git a/src/main/java/eu/hbp/mip/utils/UserActionLogging.java b/src/main/java/eu/hbp/mip/utils/UserActionLogging.java
new file mode 100644
index 000000000..745fc24a6
--- /dev/null
+++ b/src/main/java/eu/hbp/mip/utils/UserActionLogging.java
@@ -0,0 +1,23 @@
+package eu.hbp.mip.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import java.time.LocalTime;
+
+public class UserActionLogging {
+
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserActionLogging.class);
+
+    public static void LogAction(String actionName, String actionIdInfo)
+    {
+        LOGGER.info( LocalTime.now()+" User : "
+                + SecurityContextHolder.getContext().getAuthentication().getName()
+                + " called enpoint " + actionName
+                + " info "
+                + actionIdInfo);
+    }
+
+}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 000000000..3843fbca8
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,14 @@
+<configuration>
+    <appender name="FILE1" class="ch.qos.logback.core.FileAppender">
+        <file>logs/log1.txt</file>
+        <append>true</append>
+        <encoder>
+            <pattern>%msg%n</pattern>
+        </encoder>
+    </appender>
+
+
+    <logger name="eu.hbp.mip.utils" level="INFO" additivity="false">
+        <appender-ref ref="FILE1" />
+    </logger>
+</configuration>
\ No newline at end of file
-- 
GitLab


From 9b0503f3657a9dd29b1e6287ecb16353f4a48ee3 Mon Sep 17 00:00:00 2001
From: jerrypan44 <jerrypan44@gmail.com>
Date: Mon, 9 Dec 2019 13:36:22 +0000
Subject: [PATCH 8/9] implementing logout flow in spring security

---
 docker/config/application.tmpl                |  1 +
 .../configuration/SecurityConfiguration.java  | 52 ++++++++++++++++++-
 src/main/resources/logback.xml                |  6 ++-
 3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index c05c497c1..0b8ee95bc 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -30,6 +30,7 @@ hbp:
     clientSecret: {{ .Env.CLIENT_SECRET }}
     accessTokenUri: {{ default .Env.TOKEN_URI "https://services.humanbrainproject.eu/oidc/token" }}
     userAuthorizationUri: {{ default .Env.AUTH_URI "https://services.humanbrainproject.eu/oidc/authorize" }}
+    logoutUri: {{ default .Env.LOGOUT_URI }}
     tokenName: access_token
     authenticationScheme: query
     clientAuthenticationScheme: form
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 9310be3de..675d5a2e0 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -53,6 +53,18 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
+//newlyadded for logout
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.RequestEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import java.net.URI;
+
+
 // See https://spring.io/guides/tutorials/spring-boot-oauth2/ for reference about configuring OAuth2 login
 // also http://cscarioni.blogspot.ch/2013/04/pro-spring-security-and-oauth-2.html
 
@@ -76,6 +88,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
     */
    @Value("#{'${frontend.loginUrl:/login/hbp}'}")
    private String loginUrl;
+ 
+	/**
+    * Absolute URL to redirect to when logout is required
+    */
+   @Value("#{'${hbp.client.logoutUri:http://88.197.53.10:8095/auth/realms/Demo/protocol/openid-connect/logout}'}")
+   private String logoutUri;
 
    /**
     * Absolute URL to redirect to after successful login
@@ -94,6 +112,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
     */
    @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}")
    private String revokeTokenURI;
+   
+   
 
 //    @Autowired
 //    private HttpServletRequest request;
@@ -114,7 +134,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 				   //.anyRequest().authenticated()
 				   .anyRequest().hasRole("Researcher")
                    .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl))
-                   .and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
+                   .and().logout().addLogoutHandler(authLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl)
                    .and().logout().permitAll()
                    .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository())
                    .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
@@ -260,5 +280,35 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
             return String.join(",", authorities);
         }
     }
+	
+	
+	private LogoutHandler authLogoutHandler() {
+		return (request, response, authentication) -> {
+			logout();
+		};
+    }
+	
+	
+	public void logout() {
+		// POSTするリクエストパラメーターを作成
+		UserActionLogging.LogAction("refresh token ", this.oauth2ClientContext.getAccessToken().getRefreshToken().getValue());
+		RestTemplate restTemplate = new RestTemplate();
+		MultiValueMap<String, String> formParams = new LinkedMultiValueMap<>();
+		formParams.add("client_id", hbp().getClientId());
+	//        formParams.add("client_secret", registration.getClientSecret());
+		formParams.add("refresh_token", this.oauth2ClientContext.getAccessToken().getRefreshToken().getValue());
+		// リクエストヘッダーを作成
+		HttpHeaders httpHeaders = new HttpHeaders();
+		httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
+		// リクエストを作成
+		RequestEntity<MultiValueMap<String, String>> requestEntity =
+				new RequestEntity<>(formParams, httpHeaders, HttpMethod.POST,
+						//URI.create("http://88.197.53.10:8095/auth/realms/Demo/protocol/openid-connect/logout")); //todo make this parameter
+						URI.create(logoutUri)); //todo make this parameter
+		// POSTリクエスト送信(ログアウト実行)
+
+		ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
+    }
+	
    
 }
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index 3843fbca8..d1875652c 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -3,11 +3,13 @@
         <file>logs/log1.txt</file>
         <append>true</append>
         <encoder>
-            <pattern>%msg%n</pattern>
+            <pattern>%d{yyyy-MM-dd} %msg%n</pattern>
         </encoder>
     </appender>
 
-
+	<logger name="org.springframework">
+		<appender-ref ref="FILE1" />
+	</logger>
     <logger name="eu.hbp.mip.utils" level="INFO" additivity="false">
         <appender-ref ref="FILE1" />
     </logger>
-- 
GitLab


From 517613360e7a4b3e4f99e42ba55b711c6ab01212 Mon Sep 17 00:00:00 2001
From: jerry <Jerrypan44@gmail.com>
Date: Fri, 27 Dec 2019 12:52:02 +0000
Subject: [PATCH 9/9] disabling certificate validation for parametrized IP
 address

---
 docker/config/application.tmpl                |  5 +-
 src/main/java/eu/hbp/mip/MIPApplication.java  |  9 +++
 .../configuration/SecurityConfiguration.java  | 61 ++++++++++++++++++-
 src/main/resources/logback.xml                |  5 +-
 4 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl
index 0b8ee95bc..0e5fc5706 100644
--- a/docker/config/application.tmpl
+++ b/docker/config/application.tmpl
@@ -47,7 +47,7 @@ frontend:
   loginUrl: {{ default .Env.FRONTEND_LOGIN_URL "http://frontend/services/login/hbp" }}
   redirectAfterLogoutUrl: {{ default .Env.FRONTEND_AFTER_LOGOUT_URL (default .Env.LOGIN_URI "http://frontend/services/login/hbp") }}
   redirectAfterLoginUrl: {{ default .Env.FRONTEND_AFTER_LOGIN_URL "http://frontend/home" }}
-
+  
 logging:
   level:
     root: {{ default .Env.LOG_LEVEL "INFO" }}
@@ -88,4 +88,5 @@ services:
     galaxyUsername:  {{ default .Env.GALAXY_USERNAME "admin" }}
     galaxyPassword:  {{ default .Env.GALAXY_PASSWORD "password" }}
     galaxyContext:  {{ default .Env.GALAXY_CONTEXT "nativeGalaxy" }}
-
+  keycloak:
+    keycloakUrl: {{ default .Env.KEYCLOAK_URL "88.197.53.10"}}
diff --git a/src/main/java/eu/hbp/mip/MIPApplication.java b/src/main/java/eu/hbp/mip/MIPApplication.java
index df70ba78a..befb16ec9 100644
--- a/src/main/java/eu/hbp/mip/MIPApplication.java
+++ b/src/main/java/eu/hbp/mip/MIPApplication.java
@@ -4,14 +4,23 @@
 
 package eu.hbp.mip;
 
+
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
 
 @SpringBootApplication
 public class MIPApplication {
 
+	private static final Logger LOGGER = LoggerFactory.getLogger(MIPApplication.class);
+	
     public static void main(String[] args) {
         SpringApplication.run(MIPApplication.class, args);
     }
 
+
+
+	
 }
diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
index 675d5a2e0..bf17e5564 100644
--- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
+++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java
@@ -65,6 +65,18 @@ import org.springframework.util.MultiValueMap;
 import java.net.URI;
 
 
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+
 // See https://spring.io/guides/tutorials/spring-boot-oauth2/ for reference about configuring OAuth2 login
 // also http://cscarioni.blogspot.ch/2013/04/pro-spring-security-and-oauth-2.html
 
@@ -120,6 +132,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
+	   disableCertificateValidation();
        // @formatter:off
        http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
 
@@ -309,6 +322,52 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
 		ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
     }
-	
    
+   @Value("#{'${services.keycloak.keycloakUrl:88.197.53.10}'}")
+   private String keycloakUrl;
+   
+    // static {
+        // disableCertificateValidation();
+    // }
+
+    public void disableCertificateValidation() {
+		LOGGER.info("disabling certificate validation host : " + keycloakUrl);
+        // Create a trust manager that does not validate certificate chains
+        TrustManager[] trustAllCerts = new TrustManager[] {
+                new X509TrustManager() {
+                    public X509Certificate[] getAcceptedIssuers() {
+                        return new X509Certificate[0];
+                    }
+                    public void checkClientTrusted(X509Certificate[] certs, String authType) {}
+                    public void checkServerTrusted(X509Certificate[] certs, String authType) {}
+                } };
+
+
+        // Ignore differences between given hostname and certificate hostname
+        HostnameVerifier hv = new HostnameVerifier() {
+            public boolean verify(String hostname, SSLSession session) {
+				
+                // System.out.println("Warning: URL Host: " + hostname + " vs. "
+                        // + session.getPeerHost());
+                if(hostname.equals(keycloakUrl) && session.getPeerHost().equals(keycloakUrl))
+                {
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        };
+
+        // Install the all-trusting trust manager
+        try {
+            SSLContext sc = SSLContext.getInstance("SSL");
+            sc.init(null, trustAllCerts, new SecureRandom());
+            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+            HttpsURLConnection.setDefaultHostnameVerifier(hv);
+        } catch (Exception e) {}
+
+    } 
+
 }
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index d1875652c..efd7a874a 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -3,10 +3,13 @@
         <file>logs/log1.txt</file>
         <append>true</append>
         <encoder>
-            <pattern>%d{yyyy-MM-dd} %msg%n</pattern>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n</pattern>
         </encoder>
     </appender>
 
+	<logger name="eu.hbp.mip">
+		<appender-ref ref="FILE1" />
+	</logger>
 	<logger name="org.springframework">
 		<appender-ref ref="FILE1" />
 	</logger>
-- 
GitLab