Security is now completed... only token-based calls are now permitted.
This commit is contained in:
parent
55e4556167
commit
7bebf8b84b
|
@ -32,5 +32,6 @@
|
|||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||
<property name="java-output-path" value="/dmp-backend/target/classes"/>
|
||||
<property name="context-root" value="dmp-backend"/>
|
||||
<property name="java-output-path" value="/dmp-backend/target/classes"/>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="wst.jsdt.web"/>
|
||||
<installed facet="wst.jsdt.web" version="1.0"/>
|
||||
<installed facet="java" version="1.8"/>
|
||||
<installed facet="jst.web" version="3.0"/>
|
||||
<installed facet="jpt.jpa" version="2.1"/>
|
||||
<installed facet="wst.jsdt.web" version="1.0"/>
|
||||
</faceted-project>
|
||||
|
|
|
@ -98,19 +98,19 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.3.RELEASE</version>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.3.RELEASE</version>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.3.RELEASE</version>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -239,20 +239,20 @@
|
|||
<!-- Spring Security -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package rest.login;
|
||||
package login;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.security.MessageDigest;
|
||||
|
@ -71,7 +71,7 @@ public class Login {
|
|||
// create a token
|
||||
token = tokenSessionManager.generateRandomAlphanumeric(512);
|
||||
// add it to the cache
|
||||
tokenSessionManager.set(credentials.getUsername(), token);
|
||||
tokenSessionManager.set(token, credentials.getUsername());
|
||||
}
|
||||
|
||||
//get also the additional info of the user (if he has)
|
|
@ -2,15 +2,22 @@ package security;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.naming.NameAlreadyBoundException;
|
||||
|
||||
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;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import dao.entities.security.UserInfoDao;
|
||||
import entities.security.UserInfo;
|
||||
import exceptions.NonValidTokenException;
|
||||
import security.validators.GoogleTokenValidator;
|
||||
import security.validators.NativeTokenValidator;
|
||||
import security.validators.TokenValidator;
|
||||
|
||||
@Component
|
||||
public class CustomAuthenticationProvider implements AuthenticationProvider {
|
||||
|
@ -18,36 +25,49 @@ public class CustomAuthenticationProvider implements AuthenticationProvider {
|
|||
|
||||
@Autowired private UserInfoDao userInfoDao;
|
||||
|
||||
@Autowired private GoogleTokenValidator googleTokenValidator;
|
||||
@Autowired private NativeTokenValidator nativeTokenValidator;
|
||||
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
|
||||
/*
|
||||
|
||||
if (authentication != null) {
|
||||
// check whether the token is valid
|
||||
|
||||
String token = (String)authentication.getCredentials();
|
||||
GoogleTokenValidator gValidator = new GoogleTokenValidator();
|
||||
UserInfo userInfo = null;
|
||||
|
||||
TokenValidator tokenValidator = null;
|
||||
|
||||
if(TokenAuthenticationFilter.HEADER_GOOGLE_TOKEN_FIELD.equals(authentication.getPrincipal()))
|
||||
tokenValidator = googleTokenValidator;
|
||||
else if(TokenAuthenticationFilter.HEADER_NATIVE_TOKEN_FIELD.equals(authentication.getPrincipal()))
|
||||
tokenValidator = nativeTokenValidator;
|
||||
else
|
||||
throw new AuthenticationServiceException("The appropriate http headers have not been set. Please check!");
|
||||
|
||||
|
||||
try {
|
||||
userInfo = gValidator.validateToken(token);
|
||||
tokenValidator.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);
|
||||
|
||||
// if reached this point, authentication is ok
|
||||
//store to database if new
|
||||
// UserInfo existingUserInfo = userInfoDao.getByKey(userInfo.getId(), userInfo.getEmail());
|
||||
// if(existingUserInfo == null)
|
||||
// userInfoDao.create(userInfo);
|
||||
|
||||
// if reached this point, authentication is ok, so return just an instance with whatever.
|
||||
return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), new ArrayList<>());
|
||||
}
|
||||
else
|
||||
throw new AuthenticationServiceException("Authentication failed");
|
||||
*/
|
||||
|
||||
|
||||
//DELETE THIS, USE THE ABOVE
|
||||
return new UsernamePasswordAuthenticationToken("", "", new ArrayList<>());
|
||||
// //DELETE THIS, USE THE ABOVE
|
||||
// return new UsernamePasswordAuthenticationToken("", "", new ArrayList<>());
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -14,9 +14,11 @@ import org.springframework.web.filter.GenericFilterBean;
|
|||
|
||||
|
||||
public class TokenAuthenticationFilter extends GenericFilterBean {
|
||||
|
||||
private static final String HEADER_NATIVE_TOKEN_FIELD = "native-token";
|
||||
private static final String HEADER_GOOGLE_TOKEN_FIELD = "google-token";
|
||||
|
||||
public static final String HEADER_NATIVE_TOKEN_FIELD = "native-token";
|
||||
public static final String HEADER_GOOGLE_TOKEN_FIELD = "google-token";
|
||||
|
||||
public static final char HEADERNAME_USERNAME_DELIMITER = 0x1e; //specially crafted delimiter
|
||||
|
||||
@Override
|
||||
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
|
||||
|
@ -26,17 +28,17 @@ public class TokenAuthenticationFilter extends GenericFilterBean {
|
|||
String nativeToken = httpRequest.getHeader(HEADER_NATIVE_TOKEN_FIELD);
|
||||
String googleToken = httpRequest.getHeader(HEADER_GOOGLE_TOKEN_FIELD);
|
||||
|
||||
//just pass the token into the credentials object of the UsernamePasswordAuthenticationToken class
|
||||
//just pass the header, the username and the token into the credentials object of the UsernamePasswordAuthenticationToken class
|
||||
UsernamePasswordAuthenticationToken authentication = null;
|
||||
if(nativeToken != null)
|
||||
authentication = new UsernamePasswordAuthenticationToken("native-user", nativeToken);
|
||||
if(nativeToken != null)
|
||||
authentication = new UsernamePasswordAuthenticationToken(HEADER_NATIVE_TOKEN_FIELD, nativeToken);
|
||||
if(googleToken != null)
|
||||
authentication = new UsernamePasswordAuthenticationToken("google-user", nativeToken);
|
||||
authentication = new UsernamePasswordAuthenticationToken(HEADER_GOOGLE_TOKEN_FIELD, googleToken);
|
||||
|
||||
if(authentication != null) {
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
chain.doFilter(request, response);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -34,16 +34,14 @@ public class TokenSessionManager {
|
|||
.build();
|
||||
}
|
||||
|
||||
|
||||
public String get(String key) {
|
||||
return cache.getIfPresent(key);
|
||||
public String getUser(String token) {
|
||||
return cache.getIfPresent(token);
|
||||
}
|
||||
|
||||
public void set(String key, String value) {
|
||||
cache.put(key, value);
|
||||
public void set(String token, String user) {
|
||||
cache.put(token, user);
|
||||
}
|
||||
|
||||
|
||||
public String generateRandomAlphanumeric(int length) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte bytes[] = new byte[length];
|
||||
|
|
|
@ -15,7 +15,7 @@ import com.google.api.client.json.jackson2.JacksonFactory;
|
|||
import entities.security.UserInfo;
|
||||
import exceptions.NonValidTokenException;
|
||||
|
||||
public class GoogleTokenValidator {
|
||||
public class GoogleTokenValidator implements TokenValidator {
|
||||
|
||||
private static final JacksonFactory jacksonFactory = new JacksonFactory();
|
||||
private static final HttpTransport transport = new NetHttpTransport();
|
||||
|
@ -34,7 +34,8 @@ public class GoogleTokenValidator {
|
|||
}
|
||||
|
||||
|
||||
public UserInfo validateToken(String token) throws NonValidTokenException {
|
||||
@Override
|
||||
public void validateToken(String token) throws NonValidTokenException {
|
||||
|
||||
GoogleIdToken idToken = null;
|
||||
try {
|
||||
|
@ -49,22 +50,19 @@ public class GoogleTokenValidator {
|
|||
catch(IllegalArgumentException ex) {
|
||||
throw new NonValidTokenException("Could not verify token");
|
||||
}
|
||||
|
||||
|
||||
if (idToken != null) {
|
||||
Payload payload = idToken.getPayload();
|
||||
|
||||
if(idToken == null) {
|
||||
throw new NonValidTokenException("Not a valid token");
|
||||
}
|
||||
// else {
|
||||
// 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;
|
||||
|
||||
return null;
|
||||
|
||||
} else {
|
||||
throw new NonValidTokenException("Not a valid token");
|
||||
}
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package security.validators;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import exceptions.NonValidTokenException;
|
||||
import security.TokenSessionManager;
|
||||
|
||||
public class NativeTokenValidator implements TokenValidator {
|
||||
|
||||
@Autowired private TokenSessionManager tokenSessionManager;
|
||||
|
||||
@Override
|
||||
public void validateToken(String token) throws NonValidTokenException {
|
||||
String tokenUser = tokenSessionManager.getUser(token);
|
||||
if(tokenUser==null || tokenUser.isEmpty())
|
||||
throw new NonValidTokenException("Login session has expired! Need to login again!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package security.validators;
|
||||
|
||||
import exceptions.NonValidTokenException;
|
||||
|
||||
public interface TokenValidator {
|
||||
|
||||
public void validateToken(String token) throws NonValidTokenException;
|
||||
|
||||
}
|
|
@ -25,8 +25,11 @@
|
|||
</bean>
|
||||
|
||||
|
||||
<bean id="tokenSessionManager" class="security.TokenSessionManager" factory-method="getInstance">
|
||||
</bean>
|
||||
<bean id="tokenSessionManager" class="security.TokenSessionManager" factory-method="getInstance" />
|
||||
|
||||
<bean id="googleTokenValidator" class="security.validators.GoogleTokenValidator" />
|
||||
<bean id="nativeTokenValidator" class="security.validators.NativeTokenValidator" />
|
||||
|
||||
|
||||
<bean id="proxy" class="rest.proxy.Proxy">
|
||||
<constructor-arg type = "String" value = "${proxy.allowed.host}"/>
|
||||
|
@ -79,7 +82,7 @@
|
|||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
|
||||
|
||||
<bean id="organisationDao" class="dao.entities.OrganisationDaoImpl" />
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/mvc
|
||||
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-4.1.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
|
||||
|
||||
|
||||
<!-- <context:property-placeholder location="classpath*:**/dmp.properties" /> -->
|
||||
|
||||
<mvc:resources mapping="resources/**" location="/resources/" />
|
||||
<mvc:annotation-driven />
|
||||
<context:component-scan base-package="login" />
|
||||
|
||||
<bean id="multipartResolver"
|
||||
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
|
||||
<property name="maxUploadSize" value="100000000" />
|
||||
</bean>
|
||||
|
||||
<bean id="jsonConverter"
|
||||
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
|
||||
<property name="prefixJson" value="false" />
|
||||
<property name="supportedMediaTypes" value="application/json" />
|
||||
</bean>
|
||||
|
||||
<bean
|
||||
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
|
||||
<property name="messageConverters">
|
||||
<list>
|
||||
<ref bean="jsonConverter" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -1,5 +1,4 @@
|
|||
<!--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans:beans
|
||||
xmlns="http://www.springframework.org/schema/security"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
|
@ -32,18 +31,5 @@
|
|||
<beans:bean id="tokenFilter" class="security.TokenAuthenticationFilter"/>
|
||||
|
||||
|
||||
<authentication-manager>
|
||||
<authentication-provider>
|
||||
<password-encoder ref="encoder" />
|
||||
</authentication-provider>
|
||||
</authentication-manager>
|
||||
|
||||
<beans:bean id="encoder"
|
||||
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
|
||||
<beans:constructor-arg name="strength" value="11" />
|
||||
</beans:bean>
|
||||
|
||||
|
||||
|
||||
</beans:beans>
|
||||
-->
|
|
@ -3,6 +3,20 @@
|
|||
|
||||
<display-name>dmp-backend</display-name>
|
||||
|
||||
|
||||
<servlet>
|
||||
<servlet-name>dmp-backend-login</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>dmp-backend-login</servlet-name>
|
||||
<url-pattern>/login/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<listener>
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>dmp-backend-rest</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
|
@ -37,11 +51,10 @@
|
|||
</listener-class>
|
||||
</listener>
|
||||
|
||||
|
||||
<!-- ,/WEB-INF/spring-security.xml -->
|
||||
|
||||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/applicationContext.xml
|
||||
<param-value>/WEB-INF/applicationContext.xml,/WEB-INF/spring-security.xml
|
||||
</param-value>
|
||||
</context-param>
|
||||
<session-config>
|
||||
|
@ -49,17 +62,15 @@
|
|||
</session-config>
|
||||
|
||||
<!-- THIS FILTER IS FOR SPRING SECURITY -->
|
||||
<!--
|
||||
<filter>
|
||||
<filter-name>springSecurityFilterChain</filter-name>
|
||||
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>springSecurityFilterChain</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
<url-pattern>/rest/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
-->
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue