From fab68cf147979cae5f5f4286b1c4051a55ff6b6a Mon Sep 17 00:00:00 2001 From: Nikolaos Laskaris Date: Wed, 27 Sep 2017 19:15:39 +0300 Subject: [PATCH 1/4] Added security over all endpoints. Now need to provide an 'oauth2-token' parameter on each http request. --- dmp-backend/pom.xml | 56 ++++++- .../exceptions/NonValidTokenException.java | 11 ++ .../src/main/java/rest/BackendInterface.java | 1 + .../src/main/java/rest/TokenManager.java | 157 ++++++++++++++++++ .../CustomAuthenticationProvider.java | 43 +++++ .../java/security/GoogleTokenValidator.java | 77 +++++++++ .../main/java/security/SecurityConfig.java | 42 +++++ .../security/TokenAuthenticationFilter.java | 47 ++++++ .../main/java/security/entities/UserInfo.java | 95 +++++++++++ .../webapp/WEB-INF/applicationContext.xml | 10 +- .../src/main/webapp/WEB-INF/dmp.properties | 9 +- .../main/webapp/WEB-INF/spring-security.xml | 55 ++++++ dmp-backend/src/main/webapp/WEB-INF/web.xml | 19 ++- 13 files changed, 610 insertions(+), 12 deletions(-) create mode 100644 dmp-backend/src/main/java/exceptions/NonValidTokenException.java create mode 100644 dmp-backend/src/main/java/rest/TokenManager.java create mode 100644 dmp-backend/src/main/java/security/CustomAuthenticationProvider.java create mode 100644 dmp-backend/src/main/java/security/GoogleTokenValidator.java create mode 100644 dmp-backend/src/main/java/security/SecurityConfig.java create mode 100644 dmp-backend/src/main/java/security/TokenAuthenticationFilter.java create mode 100644 dmp-backend/src/main/java/security/entities/UserInfo.java create mode 100644 dmp-backend/src/main/webapp/WEB-INF/spring-security.xml diff --git a/dmp-backend/pom.xml b/dmp-backend/pom.xml index a81d94abd..799574d81 100644 --- a/dmp-backend/pom.xml +++ b/dmp-backend/pom.xml @@ -7,10 +7,14 @@ 0.0.1-SNAPSHOT war - + 1.19.0 + 1.19.0 + 0.0.1-SNAPSHOT 4.3.8.RELEASE + + 4.2.3.RELEASE 1.19.1 7.0.35 5.2.9.Final @@ -203,6 +207,54 @@ runtime + + + + + + + + + + + + com.google.apis + google-api-services-oauth2 + v2-rev75-1.19.0 + + + com.google.http-client + google-http-client-jackson2 + ${project.http.version} + + + com.google.oauth-client + google-oauth-client-jetty + ${project.oauth.version} + + + + + + + org.springframework.security + spring-security-web + ${org.springframework.security.version} + + + org.springframework.security + spring-security-config + ${org.springframework.security.version} + + + + org.springframework + spring-tx + ${org.springframework.version} + + + + org.apache.commons @@ -211,8 +263,6 @@ - - diff --git a/dmp-backend/src/main/java/exceptions/NonValidTokenException.java b/dmp-backend/src/main/java/exceptions/NonValidTokenException.java new file mode 100644 index 000000000..0d5273f5c --- /dev/null +++ b/dmp-backend/src/main/java/exceptions/NonValidTokenException.java @@ -0,0 +1,11 @@ +package exceptions; + +public class NonValidTokenException extends Exception { + + private static final long serialVersionUID = -2834659827755141154L; + + public NonValidTokenException(String msg) { + super(msg); + } + +} diff --git a/dmp-backend/src/main/java/rest/BackendInterface.java b/dmp-backend/src/main/java/rest/BackendInterface.java index 5cbfa3a69..c31a769d1 100644 --- a/dmp-backend/src/main/java/rest/BackendInterface.java +++ b/dmp-backend/src/main/java/rest/BackendInterface.java @@ -76,6 +76,7 @@ public class BackendInterface { + // FETCH BY DMP(S) @RequestMapping(method = RequestMethod.GET, value = { "/DMP" }, produces="text/plain") diff --git a/dmp-backend/src/main/java/rest/TokenManager.java b/dmp-backend/src/main/java/rest/TokenManager.java new file mode 100644 index 000000000..d302de706 --- /dev/null +++ b/dmp-backend/src/main/java/rest/TokenManager.java @@ -0,0 +1,157 @@ +//package rest; +// +//import java.io.BufferedReader; +//import java.io.IOException; +//import java.io.InputStreamReader; +//import java.io.Serializable; +//import java.io.UnsupportedEncodingException; +//import java.net.HttpURLConnection; +//import java.net.URL; +//import java.security.GeneralSecurityException; +//import java.util.Arrays; +//import java.util.Base64; +//import java.util.Collections; +//import java.util.List; +//import java.util.UUID; +// +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.CrossOrigin; +//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.RequestParam; +//import org.springframework.web.bind.annotation.ResponseBody; +//import org.springframework.web.bind.annotation.RestController; +// +//import com.fasterxml.jackson.databind.ObjectMapper; +// +//import entities.DMP; +////import io.jsonwebtoken.Claims; +////import io.jsonwebtoken.ExpiredJwtException; +////import io.jsonwebtoken.Jws; +////import io.jsonwebtoken.Jwts; +////import io.jsonwebtoken.MalformedJwtException; +////import io.jsonwebtoken.SignatureException; +////import io.jsonwebtoken.UnsupportedJwtException; +////import security.GoogleKey; +////import security.GoogleKeys; +// +// +//import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +//import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; +//import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; +//import com.google.api.client.http.HttpTransport; +//import com.google.api.client.http.apache.ApacheHttpTransport; +//import com.google.api.client.http.javanet.NetHttpTransport; +//import com.google.api.client.json.JsonFactory; +//import com.google.api.client.json.jackson2.JacksonFactory; +// +// +// +//@RestController +//@CrossOrigin +//public class TokenManager { +// +// +//// public static final String GOOGLE_KEYS_URL = "https://www.googleapis.com/oauth2/v3/certs"; +//// public static GoogleKeys GOOGLE_KEYS; +// +// private static final JacksonFactory jacksonFactory = new JacksonFactory(); +// private static final HttpTransport transport = new NetHttpTransport(); +// +// private static GoogleIdTokenVerifier verifier; +// +// private static final List clientIDs = Arrays.asList("1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com"); +// +// +// +// +// +// +// static { +// verifier = new GoogleIdTokenVerifier.Builder(transport, jacksonFactory) +// .setAudience(clientIDs) +// // Or, if multiple clients access the backend: +// //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3)) +// .build(); +// } +// +// +// +// +// @RequestMapping(method = RequestMethod.POST, value = { "/login" }, produces="text/plain") +// public @ResponseBody ResponseEntity login( +// @RequestParam("token") String token +// ){ +// +// System.out.println(token); +// +// // 1. CHECK IF IT'S A VALID TOKEN +// +// GoogleIdToken idToken = null; +// try { +// idToken = verifier.verify(token); +// } +// catch(GeneralSecurityException ex) { +// return ResponseEntity.status(HttpStatus.FORBIDDEN).body("{'reason': 'Token is not valid'}"); +// } +// catch(IOException ex) { +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("{'reason': 'Could not verify token'}"); +// } +// +// +// if (idToken != null) { +// Payload payload = idToken.getPayload(); +// +// System.out.println("============================="); +// // Print user identifier +// String userId = payload.getSubject(); +// System.out.println("User ID: " + userId); +// +// // Get profile information from payload +// String email = payload.getEmail(); +// boolean emailVerified = Boolean.valueOf(payload.getEmailVerified()); +// String name = (String) payload.get("name"); +// String pictureUrl = (String) payload.get("picture"); +// String locale = (String) payload.get("locale"); +// String familyName = (String) payload.get("family_name"); +// String givenName = (String) payload.get("given_name"); +// +// System.out.println(email); +// System.out.println(name); +// System.out.println(familyName); +// System.out.println(locale); +// System.out.println(givenName); +// System.out.println(emailVerified); +// System.out.println(pictureUrl); +// +// +// } else { +// System.out.println("Invalid ID token."); +// } +// +// +// // 2.1 IF SO, ADD USER ON THE DATABASE +// +// // 2.2 also handle it within the session (create a c\\.ustom session) +// +// +// +// return ResponseEntity.status(HttpStatus.OK).body("{'status': 'ok'}"); +// +//// try { +//// List allIDs = dMPDao.listAllIDs(); +//// return ResponseEntity.status(HttpStatus.OK).body(new ObjectMapper().writeValueAsString(allIDs)); +//// } +//// catch(Exception ex) { +//// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Serialization issue: "+ex.getMessage()); +//// } +// +// +// } +// +// +// +//} +// diff --git a/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java b/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java new file mode 100644 index 000000000..9a68d7ed7 --- /dev/null +++ b/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java @@ -0,0 +1,43 @@ +package security; + +import java.util.ArrayList; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.token.Token; +import org.springframework.security.core.token.TokenService; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +@Component +public class CustomAuthenticationProvider implements AuthenticationProvider { + + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + + System.out.println("Running authentication provider's authenticate()"); + + if(authentication == null) { + throw new AuthenticationServiceException("Authentication failed"); + } + + //authentication is ok + return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), new ArrayList<>()); + + + } + + @Override + public boolean supports(Class authentication) { + return authentication.equals(UsernamePasswordAuthenticationToken.class); + } + +} \ No newline at end of file diff --git a/dmp-backend/src/main/java/security/GoogleTokenValidator.java b/dmp-backend/src/main/java/security/GoogleTokenValidator.java new file mode 100644 index 000000000..9d4c5b204 --- /dev/null +++ b/dmp-backend/src/main/java/security/GoogleTokenValidator.java @@ -0,0 +1,77 @@ +package security; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Arrays; +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; + +import exceptions.NonValidTokenException; +import security.entities.UserInfo; + +public class GoogleTokenValidator { + + private static final JacksonFactory jacksonFactory = new JacksonFactory(); + private static final HttpTransport transport = new NetHttpTransport(); + + private static final List clientIDs = Arrays.asList("1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com"); + + private GoogleIdTokenVerifier verifier = null; + + + public GoogleTokenValidator() { + verifier = new GoogleIdTokenVerifier.Builder(transport, jacksonFactory) + .setAudience(clientIDs) + // Or, if multiple clients access the backend: + //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3)) + .build(); + } + + + public UserInfo validateToken(String token) throws NonValidTokenException { + + GoogleIdToken idToken = null; + try { + idToken = verifier.verify(token); + } + catch(GeneralSecurityException ex) { + throw new NonValidTokenException("Token is not valid -> "+ex.getMessage()); + } + catch(IOException ex) { + throw new NonValidTokenException("Could not verify token -> "+ex.getMessage()); + } + catch(IllegalArgumentException ex) { + throw new NonValidTokenException("Could not verify token"); + } + + + if (idToken != null) { + Payload payload = idToken.getPayload(); + + UserInfo userInfo = new UserInfo(payload.getSubject(), payload.getEmail(), + payload.getEmailVerified(), (String)payload.get("name"), (String)payload.get("picture"), + (String)payload.get("locale"), (String)payload.get("family_name"), (String)payload.get("given_name")); + + System.out.println(userInfo.toString()); + + return userInfo; + + } else { + throw new NonValidTokenException("Not a valid token"); + } + } + + + + + +} diff --git a/dmp-backend/src/main/java/security/SecurityConfig.java b/dmp-backend/src/main/java/security/SecurityConfig.java new file mode 100644 index 000000000..65489b787 --- /dev/null +++ b/dmp-backend/src/main/java/security/SecurityConfig.java @@ -0,0 +1,42 @@ +//package security; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.annotation.ComponentScan; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +//import org.springframework.security.config.annotation.web.builders.HttpSecurity; +//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +//import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +// +////@Configuration +//@EnableWebSecurity +//public class SecurityConfig extends WebSecurityConfigurerAdapter { +// +// @Autowired +// private CustomAuthenticationProvider authProvider; +// +// @Override +// protected void configure(AuthenticationManagerBuilder auth) throws Exception { +// System.out.println("inside SecurityConfig.configure(auth) "); +// +// auth.authenticationProvider(authProvider); +// } +// +// @Override +// protected void configure(HttpSecurity http) throws Exception { +// +// System.out.println("inside SecurityConfig.configure(http) "); +// +// http +// .authorizeRequests() +// .anyRequest() +// .authenticated() +// .and() +// .httpBasic(); +// +// http.addFilterBefore(new TokenAuthenticationFilter(), BasicAuthenticationFilter.class); +// +// } +// +//} diff --git a/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java b/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java new file mode 100644 index 000000000..3634f7cf5 --- /dev/null +++ b/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java @@ -0,0 +1,47 @@ +package security; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.GenericFilterBean; + +import exceptions.NonValidTokenException; +import security.entities.UserInfo; + +public class TokenAuthenticationFilter extends GenericFilterBean { + + @Override + public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { + + final HttpServletRequest httpRequest = (HttpServletRequest) request; + + System.out.println("in TokenAuthenticationFilter.doFilter"); + + // extract token from header + final String accessToken = httpRequest.getHeader("oauth2-token"); + if (accessToken != null) { + // get and check whether token is valid ( from DB or file wherever you are storing the token) + + GoogleTokenValidator gValidator = new GoogleTokenValidator(); + UserInfo userInfo = null; + + try { + userInfo = gValidator.validateToken(accessToken); + final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userInfo.getEmail(), accessToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + } catch (NonValidTokenException e) { + System.out.println("Could not validate a user by his token! Reason: "+e.getMessage()); + } + } + + chain.doFilter(request, response); + } + +} diff --git a/dmp-backend/src/main/java/security/entities/UserInfo.java b/dmp-backend/src/main/java/security/entities/UserInfo.java new file mode 100644 index 000000000..9cb3a19e5 --- /dev/null +++ b/dmp-backend/src/main/java/security/entities/UserInfo.java @@ -0,0 +1,95 @@ +package security.entities; + +import java.io.Serializable; + +public class UserInfo implements Serializable{ + + private static final long serialVersionUID = 1225151430484658395L; + + //required + String id = null; + String email = null; + //non required (could be left null) + Boolean emailIsVerified = null; + String name = null; + String pictureUrl = null; + String locale = null; + String familyName = null; + String givenName = null; + + + + + public UserInfo(String id, String email, Boolean emailIsVerified, String name, String pictureUrl, String locale, String familyName, String givenName) { + this.id = id; + this.email = email; + this.emailIsVerified = emailIsVerified; + this.name = name; + this.pictureUrl = pictureUrl; + this.locale = locale; + this.familyName = familyName; + this.givenName = givenName; + } + + + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public boolean isEmailIsVerified() { + return emailIsVerified; + } + public void setEmailIsVerified(boolean emailIsVerified) { + this.emailIsVerified = emailIsVerified; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getPictureUrl() { + return pictureUrl; + } + public void setPictureUrl(String pictureUrl) { + this.pictureUrl = pictureUrl; + } + public String getLocale() { + return locale; + } + public void setLocale(String locale) { + this.locale = locale; + } + public String getFamilyName() { + return familyName; + } + public void setFamilyName(String familyName) { + this.familyName = familyName; + } + public String getGivenName() { + return givenName; + } + public void setGivenName(String givenName) { + this.givenName = givenName; + } + + + + @Override + public String toString() { + return "UserInfo [id=" + id + ", email=" + email + ", emailIsVerified=" + emailIsVerified + ", name=" + name + + ", pictureUrl=" + pictureUrl + ", locale=" + locale + ", familyName=" + familyName + ", givenName=" + + givenName + "]"; + } + + +} diff --git a/dmp-backend/src/main/webapp/WEB-INF/applicationContext.xml b/dmp-backend/src/main/webapp/WEB-INF/applicationContext.xml index f50459666..a9f365b42 100644 --- a/dmp-backend/src/main/webapp/WEB-INF/applicationContext.xml +++ b/dmp-backend/src/main/webapp/WEB-INF/applicationContext.xml @@ -29,7 +29,15 @@ - + + + + + + + + + diff --git a/dmp-backend/src/main/webapp/WEB-INF/dmp.properties b/dmp-backend/src/main/webapp/WEB-INF/dmp.properties index a904f979d..5fe107785 100644 --- a/dmp-backend/src/main/webapp/WEB-INF/dmp.properties +++ b/dmp-backend/src/main/webapp/WEB-INF/dmp.properties @@ -5,9 +5,9 @@ ##########################Persistence########################################## persistence.jdbc.driver = org.postgresql.Driver -persistence.jdbc.url = jdbc:postgresql://localhost:5432/db -persistence.dbusername = db-user -persistence.dbpassword = db-pass +persistence.jdbc.url = jdbc:postgresql://develdb1.madgik.di.uoa.gr:5432/dmptool +persistence.dbusername = dmptool +persistence.dbpassword = dmpt00lu$r ##########################/Persistence########################################## @@ -42,5 +42,4 @@ persistence.hibernate.connectionpool.c3p0.idle_connection_test_period = 3600 persistence.hibernate.connectionpool.c3p0.test_connection_on_checkin = true persistence.hibernate.connectionpool.c3p0.test_connection_on_checkout = false persistence.hibernate.connectionpool.c3p0.preferred_test_query = select 1 -########################Persistence/Hibernate/Connection pool#################### - +########################Persistence/Hibernate/Connection pool#################### \ No newline at end of file diff --git a/dmp-backend/src/main/webapp/WEB-INF/spring-security.xml b/dmp-backend/src/main/webapp/WEB-INF/spring-security.xml new file mode 100644 index 000000000..28e58abf8 --- /dev/null +++ b/dmp-backend/src/main/webapp/WEB-INF/spring-security.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dmp-backend/src/main/webapp/WEB-INF/web.xml b/dmp-backend/src/main/webapp/WEB-INF/web.xml index f900b4a52..0c3aa66c5 100644 --- a/dmp-backend/src/main/webapp/WEB-INF/web.xml +++ b/dmp-backend/src/main/webapp/WEB-INF/web.xml @@ -31,11 +31,24 @@ contextConfigLocation - - /WEB-INF/applicationContext.xml - + /WEB-INF/applicationContext.xml,/WEB-INF/spring-security.xml + 30 + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + springSecurityFilterChain + /* + + + + + \ No newline at end of file From 7b1f3b5a9c2206bd9555e218438bc5808b4b3495 Mon Sep 17 00:00:00 2001 From: Nikolaos Laskaris Date: Thu, 28 Sep 2017 11:10:20 +0200 Subject: [PATCH 2/4] Updated DataManagementPlanDB.sql --- dmp-db-scema/DataManagementPlanDB.sql | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/dmp-db-scema/DataManagementPlanDB.sql b/dmp-db-scema/DataManagementPlanDB.sql index 6bfa4beff..2168050f7 100644 --- a/dmp-db-scema/DataManagementPlanDB.sql +++ b/dmp-db-scema/DataManagementPlanDB.sql @@ -1,4 +1,3 @@ - SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; @@ -26,6 +25,7 @@ drop table if exists "Registry" cascade; drop table if exists "DatasetService" cascade; drop table if exists "DatasetRegistry" cascade; drop table if exists "DatasetDataRepository" cascade; +drop table if exists "UserInfo" cascade; -- CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; @@ -420,12 +420,12 @@ CREATE TABLE "DatasetDataRepository" ( "ID" uuid DEFAULT uuid_generate_v4() NOT NULL ); + ALTER TABLE "DatasetDataRepository" OWNER TO dmptool; COMMENT ON TABLE "DatasetDataRepository" IS 'Linking Dataset to DataRepository'; - ALTER TABLE ONLY "DatasetDataRepository" ADD CONSTRAINT "DatasetDataRepositoryDatasetReference" FOREIGN KEY ("Dataset") REFERENCES "Dataset"("ID"); @@ -447,6 +447,21 @@ ALTER TABLE ONLY "DatasetService" ADD CONSTRAINT "DatasetServiceServiceReference" FOREIGN KEY ("Service") REFERENCES "Service"("ID"); +CREATE TABLE "UserInfo" ( + "autoid" uuid DEFAULT uuid_generate_v4() NOT NULL, + "id" character varying(500), + "email" character varying(250), + "emailIsVerified" boolean, + "name" character varying(250), + "pictureUrl" character varying(500), + "locale" character varying(50), + "familyName" character varying(250), + "givenName" character varying(250), + "additionalinfo" xml, + PRIMARY KEY (id, email) +); + + REVOKE ALL ON SCHEMA public FROM PUBLIC; REVOKE ALL ON SCHEMA public FROM postgres; GRANT ALL ON SCHEMA public TO postgres; From d8021286418b80fd57ebd5e65b7a8a9bf7622c73 Mon Sep 17 00:00:00 2001 From: Nikolaos Laskaris Date: Thu, 28 Sep 2017 13:32:03 +0300 Subject: [PATCH 3/4] Cleaned up a little bit the security management code. Also added the userinfo table to hold information for loggedin users. --- .../dao/entities/security/UserInfoDao.java | 12 ++ .../entities/security/UserInfoDaoImpl.java | 37 +++++ .../main/java/entities/security/UserInfo.java | 151 +++++++++++++++++ .../src/main/java/rest/TokenManager.java | 157 ------------------ .../CustomAuthenticationProvider.java | 28 +++- .../java/security/GoogleTokenValidator.java | 6 +- .../main/java/security/SecurityConfig.java | 42 ----- .../security/TokenAuthenticationFilter.java | 27 +-- .../main/java/security/entities/UserInfo.java | 95 ----------- .../webapp/WEB-INF/applicationContext.xml | 1 + 10 files changed, 237 insertions(+), 319 deletions(-) create mode 100644 dmp-backend/src/main/java/dao/entities/security/UserInfoDao.java create mode 100644 dmp-backend/src/main/java/dao/entities/security/UserInfoDaoImpl.java create mode 100644 dmp-backend/src/main/java/entities/security/UserInfo.java delete mode 100644 dmp-backend/src/main/java/rest/TokenManager.java delete mode 100644 dmp-backend/src/main/java/security/SecurityConfig.java delete mode 100644 dmp-backend/src/main/java/security/entities/UserInfo.java diff --git a/dmp-backend/src/main/java/dao/entities/security/UserInfoDao.java b/dmp-backend/src/main/java/dao/entities/security/UserInfoDao.java new file mode 100644 index 000000000..0922b1fbc --- /dev/null +++ b/dmp-backend/src/main/java/dao/entities/security/UserInfoDao.java @@ -0,0 +1,12 @@ +package dao.entities.security; + +import java.util.UUID; + +import dao.Dao; +import entities.security.UserInfo; + +public interface UserInfoDao extends Dao { + + public UserInfo getByKey(String id, String email); + +} \ No newline at end of file diff --git a/dmp-backend/src/main/java/dao/entities/security/UserInfoDaoImpl.java b/dmp-backend/src/main/java/dao/entities/security/UserInfoDaoImpl.java new file mode 100644 index 000000000..3f257d8f5 --- /dev/null +++ b/dmp-backend/src/main/java/dao/entities/security/UserInfoDaoImpl.java @@ -0,0 +1,37 @@ +package dao.entities.security; + +import java.util.List; +import java.util.UUID; + +import javax.persistence.NoResultException; +import javax.persistence.TypedQuery; + +import dao.JpaDao; +import entities.security.UserInfo; + + +public class UserInfoDaoImpl extends JpaDao implements UserInfoDao { + + public UserInfo loadDetails(UserInfo t) { + // TODO Auto-generated method stub + return null; + } + + + + @Override + public UserInfo getByKey(String id, String email) { + String queryString = "FROM UserInfo userInfo where userInfo.id = :userInfoID and userInfo.email = :userInfoEmail"; + TypedQuery typedQuery = entityManager.createQuery(queryString, UserInfo.class); + typedQuery.setParameter("userInfoID", id); + typedQuery.setParameter("userInfoEmail", email); + try { + return typedQuery.getSingleResult(); + } + catch(NoResultException ex) { + return null; + } + } + + +} \ No newline at end of file diff --git a/dmp-backend/src/main/java/entities/security/UserInfo.java b/dmp-backend/src/main/java/entities/security/UserInfo.java new file mode 100644 index 000000000..1e95a0c21 --- /dev/null +++ b/dmp-backend/src/main/java/entities/security/UserInfo.java @@ -0,0 +1,151 @@ +package entities.security; + +import java.io.Serializable; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + + +@Entity +@Table(name="\"UserInfo\"") +@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="autoid") +public class UserInfo implements Serializable{ + + private static final long serialVersionUID = 1225151430484658395L; + + @Id + @GeneratedValue + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Column(name = "autoid", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID autoid; + + //required + @Column(name = "id") + String id = null; + @Column(name = "email") + String email = null; + + //non required + @Column(name = "\"emailIsVerified\"", nullable = true) + Boolean emailIsVerified = null; + @Column(name = "name", nullable = true) + String name = null; + @Column(name = "\"pictureUrl\"", nullable = true) + String pictureUrl = null; + @Column(name = "locale", nullable = true) + String locale = null; + @Column(name = "\"familyName\"", nullable = true) + String familyName = null; + @Column(name = "\"givenName\"", nullable = true) + String givenName = null; + + + @Type(type="typedefinition.XMLType") + @Column(name = "additionalinfo", columnDefinition = "xml", nullable = true) + private String additionalinfo; + + + + public UserInfo () {} + + public UserInfo(String id, String email, Boolean emailIsVerified, String name, String pictureUrl, String locale, String familyName, String givenName, String additionalinfo) { + this.id = id; + this.email = email; + this.emailIsVerified = emailIsVerified; + this.name = name; + this.pictureUrl = pictureUrl; + this.locale = locale; + this.familyName = familyName; + this.givenName = givenName; + this.additionalinfo = additionalinfo; + } + + + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public boolean isEmailIsVerified() { + return emailIsVerified; + } + public void setEmailIsVerified(boolean emailIsVerified) { + this.emailIsVerified = emailIsVerified; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getPictureUrl() { + return pictureUrl; + } + public void setPictureUrl(String pictureUrl) { + this.pictureUrl = pictureUrl; + } + public String getLocale() { + return locale; + } + public void setLocale(String locale) { + this.locale = locale; + } + public String getFamilyName() { + return familyName; + } + public void setFamilyName(String familyName) { + this.familyName = familyName; + } + public String getGivenName() { + return givenName; + } + public void setGivenName(String givenName) { + this.givenName = givenName; + } + + + public Boolean getEmailIsVerified() { + return emailIsVerified; + } + + public void setEmailIsVerified(Boolean emailIsVerified) { + this.emailIsVerified = emailIsVerified; + } + + public String getAdditionalinfo() { + return additionalinfo; + } + + public void setAdditionalinfo(String additionalinfo) { + this.additionalinfo = additionalinfo; + } + + @Override + public String toString() { + return "UserInfo [id=" + id + ", email=" + email + ", emailIsVerified=" + emailIsVerified + + ", name=" + name + ", pictureUrl=" + pictureUrl + ", locale=" + locale + ", familyName=" + familyName + + ", givenName=" + givenName + ", additionalinfo=" + additionalinfo + "]"; + } + + + + +} diff --git a/dmp-backend/src/main/java/rest/TokenManager.java b/dmp-backend/src/main/java/rest/TokenManager.java deleted file mode 100644 index d302de706..000000000 --- a/dmp-backend/src/main/java/rest/TokenManager.java +++ /dev/null @@ -1,157 +0,0 @@ -//package rest; -// -//import java.io.BufferedReader; -//import java.io.IOException; -//import java.io.InputStreamReader; -//import java.io.Serializable; -//import java.io.UnsupportedEncodingException; -//import java.net.HttpURLConnection; -//import java.net.URL; -//import java.security.GeneralSecurityException; -//import java.util.Arrays; -//import java.util.Base64; -//import java.util.Collections; -//import java.util.List; -//import java.util.UUID; -// -//import org.springframework.http.HttpStatus; -//import org.springframework.http.ResponseEntity; -//import org.springframework.web.bind.annotation.CrossOrigin; -//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.RequestParam; -//import org.springframework.web.bind.annotation.ResponseBody; -//import org.springframework.web.bind.annotation.RestController; -// -//import com.fasterxml.jackson.databind.ObjectMapper; -// -//import entities.DMP; -////import io.jsonwebtoken.Claims; -////import io.jsonwebtoken.ExpiredJwtException; -////import io.jsonwebtoken.Jws; -////import io.jsonwebtoken.Jwts; -////import io.jsonwebtoken.MalformedJwtException; -////import io.jsonwebtoken.SignatureException; -////import io.jsonwebtoken.UnsupportedJwtException; -////import security.GoogleKey; -////import security.GoogleKeys; -// -// -//import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; -//import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; -//import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; -//import com.google.api.client.http.HttpTransport; -//import com.google.api.client.http.apache.ApacheHttpTransport; -//import com.google.api.client.http.javanet.NetHttpTransport; -//import com.google.api.client.json.JsonFactory; -//import com.google.api.client.json.jackson2.JacksonFactory; -// -// -// -//@RestController -//@CrossOrigin -//public class TokenManager { -// -// -//// public static final String GOOGLE_KEYS_URL = "https://www.googleapis.com/oauth2/v3/certs"; -//// public static GoogleKeys GOOGLE_KEYS; -// -// private static final JacksonFactory jacksonFactory = new JacksonFactory(); -// private static final HttpTransport transport = new NetHttpTransport(); -// -// private static GoogleIdTokenVerifier verifier; -// -// private static final List clientIDs = Arrays.asList("1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com"); -// -// -// -// -// -// -// static { -// verifier = new GoogleIdTokenVerifier.Builder(transport, jacksonFactory) -// .setAudience(clientIDs) -// // Or, if multiple clients access the backend: -// //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3)) -// .build(); -// } -// -// -// -// -// @RequestMapping(method = RequestMethod.POST, value = { "/login" }, produces="text/plain") -// public @ResponseBody ResponseEntity login( -// @RequestParam("token") String token -// ){ -// -// System.out.println(token); -// -// // 1. CHECK IF IT'S A VALID TOKEN -// -// GoogleIdToken idToken = null; -// try { -// idToken = verifier.verify(token); -// } -// catch(GeneralSecurityException ex) { -// return ResponseEntity.status(HttpStatus.FORBIDDEN).body("{'reason': 'Token is not valid'}"); -// } -// catch(IOException ex) { -// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("{'reason': 'Could not verify token'}"); -// } -// -// -// if (idToken != null) { -// Payload payload = idToken.getPayload(); -// -// System.out.println("============================="); -// // Print user identifier -// String userId = payload.getSubject(); -// System.out.println("User ID: " + userId); -// -// // Get profile information from payload -// String email = payload.getEmail(); -// boolean emailVerified = Boolean.valueOf(payload.getEmailVerified()); -// String name = (String) payload.get("name"); -// String pictureUrl = (String) payload.get("picture"); -// String locale = (String) payload.get("locale"); -// String familyName = (String) payload.get("family_name"); -// String givenName = (String) payload.get("given_name"); -// -// System.out.println(email); -// System.out.println(name); -// System.out.println(familyName); -// System.out.println(locale); -// System.out.println(givenName); -// System.out.println(emailVerified); -// System.out.println(pictureUrl); -// -// -// } else { -// System.out.println("Invalid ID token."); -// } -// -// -// // 2.1 IF SO, ADD USER ON THE DATABASE -// -// // 2.2 also handle it within the session (create a c\\.ustom session) -// -// -// -// return ResponseEntity.status(HttpStatus.OK).body("{'status': 'ok'}"); -// -//// try { -//// List allIDs = dMPDao.listAllIDs(); -//// return ResponseEntity.status(HttpStatus.OK).body(new ObjectMapper().writeValueAsString(allIDs)); -//// } -//// catch(Exception ex) { -//// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Serialization issue: "+ex.getMessage()); -//// } -// -// -// } -// -// -// -//} -// diff --git a/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java b/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java index 9a68d7ed7..f787b4787 100644 --- a/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java +++ b/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import javax.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -16,18 +17,39 @@ import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import dao.entities.security.UserInfoDao; +import entities.security.UserInfo; +import exceptions.NonValidTokenException; + @Component public class CustomAuthenticationProvider implements AuthenticationProvider { + @Autowired private UserInfoDao userInfoDao; + + @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { - System.out.println("Running authentication provider's authenticate()"); - if(authentication == null) { - throw new AuthenticationServiceException("Authentication failed"); + if (authentication != null) { + // check whether the token is valid + String token = (String)authentication.getCredentials(); + GoogleTokenValidator gValidator = new GoogleTokenValidator(); + UserInfo userInfo = null; + try { + userInfo = gValidator.validateToken(token); + } catch (NonValidTokenException e) { + System.out.println("Could not validate a user by his token! Reason: "+e.getMessage()); + throw new AuthenticationServiceException("Token validation failed - Not a valid token"); + } + //store to database if new + UserInfo existingUserInfo = userInfoDao.getByKey(userInfo.getId(), userInfo.getEmail()); + if(existingUserInfo == null) + userInfoDao.create(userInfo); } + else + throw new AuthenticationServiceException("Authentication failed"); //authentication is ok return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), new ArrayList<>()); diff --git a/dmp-backend/src/main/java/security/GoogleTokenValidator.java b/dmp-backend/src/main/java/security/GoogleTokenValidator.java index 9d4c5b204..d9651989a 100644 --- a/dmp-backend/src/main/java/security/GoogleTokenValidator.java +++ b/dmp-backend/src/main/java/security/GoogleTokenValidator.java @@ -15,8 +15,8 @@ import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; +import entities.security.UserInfo; import exceptions.NonValidTokenException; -import security.entities.UserInfo; public class GoogleTokenValidator { @@ -59,9 +59,9 @@ public class GoogleTokenValidator { UserInfo userInfo = new UserInfo(payload.getSubject(), payload.getEmail(), payload.getEmailVerified(), (String)payload.get("name"), (String)payload.get("picture"), - (String)payload.get("locale"), (String)payload.get("family_name"), (String)payload.get("given_name")); + (String)payload.get("locale"), (String)payload.get("family_name"), (String)payload.get("given_name"), ""); - System.out.println(userInfo.toString()); +// System.out.println(userInfo.toString()); return userInfo; diff --git a/dmp-backend/src/main/java/security/SecurityConfig.java b/dmp-backend/src/main/java/security/SecurityConfig.java deleted file mode 100644 index 65489b787..000000000 --- a/dmp-backend/src/main/java/security/SecurityConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -//package security; -// -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.context.annotation.ComponentScan; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -//import org.springframework.security.config.annotation.web.builders.HttpSecurity; -//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -//import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; -// -////@Configuration -//@EnableWebSecurity -//public class SecurityConfig extends WebSecurityConfigurerAdapter { -// -// @Autowired -// private CustomAuthenticationProvider authProvider; -// -// @Override -// protected void configure(AuthenticationManagerBuilder auth) throws Exception { -// System.out.println("inside SecurityConfig.configure(auth) "); -// -// auth.authenticationProvider(authProvider); -// } -// -// @Override -// protected void configure(HttpSecurity http) throws Exception { -// -// System.out.println("inside SecurityConfig.configure(http) "); -// -// http -// .authorizeRequests() -// .anyRequest() -// .authenticated() -// .and() -// .httpBasic(); -// -// http.addFilterBefore(new TokenAuthenticationFilter(), BasicAuthenticationFilter.class); -// -// } -// -//} diff --git a/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java b/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java index 3634f7cf5..d4a4cf5f0 100644 --- a/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java +++ b/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java @@ -12,35 +12,24 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.GenericFilterBean; +import entities.security.UserInfo; import exceptions.NonValidTokenException; -import security.entities.UserInfo; public class TokenAuthenticationFilter extends GenericFilterBean { + private static final String HEADER_TOKEN_FIELD = "oauth2-token"; + + @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { final HttpServletRequest httpRequest = (HttpServletRequest) request; - System.out.println("in TokenAuthenticationFilter.doFilter"); + final String accessToken = httpRequest.getHeader(HEADER_TOKEN_FIELD); + //just pass the token into the credentials object of the UsernamePasswordAuthenticationToken class + final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("google-user", accessToken); + SecurityContextHolder.getContext().setAuthentication(authentication); - // extract token from header - final String accessToken = httpRequest.getHeader("oauth2-token"); - if (accessToken != null) { - // get and check whether token is valid ( from DB or file wherever you are storing the token) - - GoogleTokenValidator gValidator = new GoogleTokenValidator(); - UserInfo userInfo = null; - - try { - userInfo = gValidator.validateToken(accessToken); - final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userInfo.getEmail(), accessToken); - SecurityContextHolder.getContext().setAuthentication(authentication); - } catch (NonValidTokenException e) { - System.out.println("Could not validate a user by his token! Reason: "+e.getMessage()); - } - } - chain.doFilter(request, response); } diff --git a/dmp-backend/src/main/java/security/entities/UserInfo.java b/dmp-backend/src/main/java/security/entities/UserInfo.java deleted file mode 100644 index 9cb3a19e5..000000000 --- a/dmp-backend/src/main/java/security/entities/UserInfo.java +++ /dev/null @@ -1,95 +0,0 @@ -package security.entities; - -import java.io.Serializable; - -public class UserInfo implements Serializable{ - - private static final long serialVersionUID = 1225151430484658395L; - - //required - String id = null; - String email = null; - //non required (could be left null) - Boolean emailIsVerified = null; - String name = null; - String pictureUrl = null; - String locale = null; - String familyName = null; - String givenName = null; - - - - - public UserInfo(String id, String email, Boolean emailIsVerified, String name, String pictureUrl, String locale, String familyName, String givenName) { - this.id = id; - this.email = email; - this.emailIsVerified = emailIsVerified; - this.name = name; - this.pictureUrl = pictureUrl; - this.locale = locale; - this.familyName = familyName; - this.givenName = givenName; - } - - - - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getEmail() { - return email; - } - public void setEmail(String email) { - this.email = email; - } - public boolean isEmailIsVerified() { - return emailIsVerified; - } - public void setEmailIsVerified(boolean emailIsVerified) { - this.emailIsVerified = emailIsVerified; - } - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String getPictureUrl() { - return pictureUrl; - } - public void setPictureUrl(String pictureUrl) { - this.pictureUrl = pictureUrl; - } - public String getLocale() { - return locale; - } - public void setLocale(String locale) { - this.locale = locale; - } - public String getFamilyName() { - return familyName; - } - public void setFamilyName(String familyName) { - this.familyName = familyName; - } - public String getGivenName() { - return givenName; - } - public void setGivenName(String givenName) { - this.givenName = givenName; - } - - - - @Override - public String toString() { - return "UserInfo [id=" + id + ", email=" + email + ", emailIsVerified=" + emailIsVerified + ", name=" + name - + ", pictureUrl=" + pictureUrl + ", locale=" + locale + ", familyName=" + familyName + ", givenName=" - + givenName + "]"; - } - - -} diff --git a/dmp-backend/src/main/webapp/WEB-INF/applicationContext.xml b/dmp-backend/src/main/webapp/WEB-INF/applicationContext.xml index a9f365b42..0f6721e4b 100644 --- a/dmp-backend/src/main/webapp/WEB-INF/applicationContext.xml +++ b/dmp-backend/src/main/webapp/WEB-INF/applicationContext.xml @@ -95,6 +95,7 @@ + From b17a1e272b69199ef085b2154eeba8b16c4cdb54 Mon Sep 17 00:00:00 2001 From: Nikolaos Laskaris Date: Thu, 28 Sep 2017 13:41:08 +0300 Subject: [PATCH 4/4] added a check on token --- .../java/security/CustomAuthenticationProvider.java | 13 ++++--------- .../main/java/security/GoogleTokenValidator.java | 3 --- .../java/security/TokenAuthenticationFilter.java | 5 ++--- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java b/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java index f787b4787..dd797a0bc 100644 --- a/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java +++ b/dmp-backend/src/main/java/security/CustomAuthenticationProvider.java @@ -2,7 +2,6 @@ package security; import java.util.ArrayList; -import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; @@ -10,12 +9,7 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.token.Token; -import org.springframework.security.core.token.TokenService; import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; import dao.entities.security.UserInfoDao; import entities.security.UserInfo; @@ -47,14 +41,15 @@ public class CustomAuthenticationProvider implements AuthenticationProvider { UserInfo existingUserInfo = userInfoDao.getByKey(userInfo.getId(), userInfo.getEmail()); if(existingUserInfo == null) userInfoDao.create(userInfo); + + // if reached this point, authentication is ok + return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), new ArrayList<>()); } else throw new AuthenticationServiceException("Authentication failed"); - //authentication is ok - return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), new ArrayList<>()); - + } @Override diff --git a/dmp-backend/src/main/java/security/GoogleTokenValidator.java b/dmp-backend/src/main/java/security/GoogleTokenValidator.java index d9651989a..8e133d93c 100644 --- a/dmp-backend/src/main/java/security/GoogleTokenValidator.java +++ b/dmp-backend/src/main/java/security/GoogleTokenValidator.java @@ -5,9 +5,6 @@ import java.security.GeneralSecurityException; import java.util.Arrays; import java.util.List; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; diff --git a/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java b/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java index d4a4cf5f0..f9e968e33 100644 --- a/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java +++ b/dmp-backend/src/main/java/security/TokenAuthenticationFilter.java @@ -12,8 +12,6 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.GenericFilterBean; -import entities.security.UserInfo; -import exceptions.NonValidTokenException; public class TokenAuthenticationFilter extends GenericFilterBean { @@ -25,7 +23,8 @@ public class TokenAuthenticationFilter extends GenericFilterBean { final HttpServletRequest httpRequest = (HttpServletRequest) request; - final String accessToken = httpRequest.getHeader(HEADER_TOKEN_FIELD); + String accessToken = httpRequest.getHeader(HEADER_TOKEN_FIELD); + if(accessToken==null) accessToken = ""; //just pass the token into the credentials object of the UsernamePasswordAuthenticationToken class final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("google-user", accessToken); SecurityContextHolder.getContext().setAuthentication(authentication);