From 41c409daa87b048ea8f907e8b98367435b6b0fbb Mon Sep 17 00:00:00 2001 From: michada Date: Tue, 11 Feb 2014 22:50:35 +0100 Subject: [PATCH] Added login capabilities. Access to any resource except index.html can be restricted enabling the LoginFilter in the web.xml configuration file. It is currently disabled. Old index.html moved to main.html and replaced with an index.html that contains a login form. --- pom.xml | 6 + .../java/es/uvigo/esei/daa/LoginFilter.java | 113 ++++++++++++++++++ .../java/es/uvigo/esei/daa/dao/UsersDAO.java | 58 +++++++++ src/main/resources/mysql-with-inserts.sql | 27 +++++ src/main/resources/mysql.sql | 16 +++ src/main/webapp/WEB-INF/web.xml | 20 ++-- src/main/webapp/index.html | 20 +--- src/main/webapp/js/view/people.js | 14 +-- src/main/webapp/main.html | 23 ++++ 9 files changed, 269 insertions(+), 28 deletions(-) create mode 100644 src/main/java/es/uvigo/esei/daa/LoginFilter.java create mode 100644 src/main/java/es/uvigo/esei/daa/dao/UsersDAO.java create mode 100644 src/main/resources/mysql-with-inserts.sql create mode 100644 src/main/resources/mysql.sql create mode 100644 src/main/webapp/main.html diff --git a/pom.xml b/pom.xml index e4fef9d..6745044 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,12 @@ mysql-connector-java 5.1.28 + + + commons-codec + commons-codec + 1.9 + diff --git a/src/main/java/es/uvigo/esei/daa/LoginFilter.java b/src/main/java/es/uvigo/esei/daa/LoginFilter.java new file mode 100644 index 0000000..e8c1586 --- /dev/null +++ b/src/main/java/es/uvigo/esei/daa/LoginFilter.java @@ -0,0 +1,113 @@ +package es.uvigo.esei.daa; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import es.uvigo.esei.daa.dao.DAOException; +import es.uvigo.esei.daa.dao.UsersDAO; + +public class LoginFilter implements Filter { + @Override + public void doFilter( + ServletRequest request, + ServletResponse response, + FilterChain chain + ) throws IOException, ServletException { + final HttpServletRequest httpRequest = (HttpServletRequest) request; + final HttpServletResponse httpResponse = (HttpServletResponse) response; + + if (isLogoutPath(httpRequest)) { + removeCookie(httpResponse); + redirectToIndex(httpRequest, httpResponse); + } else if (isIndexPath(httpRequest) || + checkLogin(httpRequest, httpResponse) || + checkToken(httpRequest) + ) { + chain.doFilter(request, response); + } else { + redirectToIndex(httpRequest, httpResponse); + } + } + + private void redirectToIndex( + HttpServletRequest httpRequest, + HttpServletResponse httpResponse + ) throws IOException { + httpResponse.sendRedirect(httpRequest.getContextPath() + "/index.html"); + } + + private void removeCookie(HttpServletResponse httpResponse) { + final Cookie cookie = new Cookie("token", ""); + cookie.setMaxAge(0); + httpResponse.addCookie(cookie); + } + + private boolean isLogoutPath(HttpServletRequest httpRequest) { + return httpRequest.getServletPath().equals("/logout"); + } + + private boolean isIndexPath(HttpServletRequest httpRequest) { + return httpRequest.getServletPath().equals("/index.html"); + } + + private boolean checkLogin(HttpServletRequest httpRequest, HttpServletResponse response) { + final String login = httpRequest.getParameter("login"); + final String password = httpRequest.getParameter("password"); + + if (login != null && password != null) { + try { + final UsersDAO dao = new UsersDAO(); + final String token = dao.checkLogin(login, password); + + if (token == null) { + return false; + } else { + response.addCookie(new Cookie("token", token)); + + return true; + } + } catch (DAOException e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + + private boolean checkToken(HttpServletRequest httpRequest) { + final Cookie[] cookies = httpRequest.getCookies(); + + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie.getName().equals("token")) { + try { + return new UsersDAO().checkToken(cookie.getValue()) != null; + } catch (DAOException e) { + e.printStackTrace(); + return false; + } + } + } + } + + return false; + } + + @Override + public void init(FilterConfig config) throws ServletException { + } + + @Override + public void destroy() { + } +} diff --git a/src/main/java/es/uvigo/esei/daa/dao/UsersDAO.java b/src/main/java/es/uvigo/esei/daa/dao/UsersDAO.java new file mode 100644 index 0000000..66ef5c2 --- /dev/null +++ b/src/main/java/es/uvigo/esei/daa/dao/UsersDAO.java @@ -0,0 +1,58 @@ +package es.uvigo.esei.daa.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.apache.commons.codec.digest.DigestUtils; + +public class UsersDAO extends DAO { + public String checkLogin(String login, String password) throws DAOException { + final String shaPassword = DigestUtils.sha256Hex(password); + + try (final Connection conn = this.getConnection()) { + final String query = "SELECT password FROM users WHERE login=?"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setString(1, login); + + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + final String dbPassword = result.getString("password"); + + if (shaPassword.equals(dbPassword)) { + return DigestUtils.sha256Hex(login + dbPassword); + } else { + return null; + } + } else { + return null; + } + } + } + } catch (SQLException e) { + throw new DAOException(e); + } + } + + public String checkToken(String token) throws DAOException { + try (final Connection conn = this.getConnection()) { + final String query = "SELECT login FROM users WHERE sha2(concat(login, password), 256)=?"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setString(1, token); + + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + return result.getString("login"); + } else { + return null; + } + } + } + } catch (SQLException e) { + throw new DAOException(e); + } + } +} diff --git a/src/main/resources/mysql-with-inserts.sql b/src/main/resources/mysql-with-inserts.sql new file mode 100644 index 0000000..2210aa5 --- /dev/null +++ b/src/main/resources/mysql-with-inserts.sql @@ -0,0 +1,27 @@ +CREATE DATABASE `daaexample`; + +CREATE TABLE `daaexample`.`people` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(50) DEFAULT NULL, + `surname` varchar(100) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `daaexample`.`users` ( + `login` varchar(100) NOT NULL, + `password` varbinary(64) DEFAULT NULL, + PRIMARY KEY (`login`) +); + +GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa'; + +INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Antón','Pérez'); +INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Manuel','Martínez'); +INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Laura','Reboredo'); +INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Perico','Palotes'); +INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Ana','María'); +INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'María','Nuevo'); +INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Alba','Fernández'); +INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Asunción','Jiménez'); + +INSERT INTO `daaexample`.`users` (`login`,`password`) VALUES ('mrjato', '59189332a4abf8ddf66fde068cad09eb563b4bd974f7663d97ff6852a7910a73'); diff --git a/src/main/resources/mysql.sql b/src/main/resources/mysql.sql new file mode 100644 index 0000000..88e93d1 --- /dev/null +++ b/src/main/resources/mysql.sql @@ -0,0 +1,16 @@ +CREATE DATABASE `daaexample`; + +CREATE TABLE `daaexample`.`people` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(50) DEFAULT NULL, + `surname` varchar(100) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `daaexample`.`users` ( + `login` varchar(100) NOT NULL, + `password` varbinary(64) DEFAULT NULL, + PRIMARY KEY (`login`) +); + +GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa'; \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 8f98f73..623a8d2 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -3,7 +3,8 @@ xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> - DAAExampleTMP + DAAExample + index.html index.htm @@ -12,15 +13,18 @@ default.htm default.jsp + DAA Example DB Connection jdbc/daaexample javax.sql.DataSource Container + javax.ws.rs.core.Application + com.sun.jersey.api.json.POJOMappingFeature true @@ -30,10 +34,12 @@ /rest/* - + \ No newline at end of file diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index 74acdfc..87a10ae 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -2,21 +2,13 @@ -DAA Example +DAA Example - Login -
-

People

-
- - - - +
+
Login:
+
Password:
+
+
\ No newline at end of file diff --git a/src/main/webapp/js/view/people.js b/src/main/webapp/js/view/people.js index d459d50..315d965 100644 --- a/src/main/webapp/js/view/people.js +++ b/src/main/webapp/js/view/people.js @@ -50,6 +50,13 @@ function formToPerson() { }; } +function personToForm(person) { + var form = $(peopleFormQuery); + form.find('input[name="id"]').val(person.id); + form.find('input[name="name"]').val(person.name); + form.find('input[name="surname"]').val(person.surname); +} + function rowToPerson(id) { var row = $('#person-' + id); @@ -60,13 +67,6 @@ function rowToPerson(id) { }; } -function personToForm(person) { - var form = $(peopleFormQuery); - form.find('input[name="id"]').val(person.id); - form.find('input[name="name"]').val(person.name); - form.find('input[name="surname"]').val(person.surname); -} - function isEditing() { return $(peopleFormQuery + ' input[name="id"]').val() != ""; } diff --git a/src/main/webapp/main.html b/src/main/webapp/main.html new file mode 100644 index 0000000..d8f1384 --- /dev/null +++ b/src/main/webapp/main.html @@ -0,0 +1,23 @@ + + + + +DAA Example + + +
+

People

+ Logout +
+ + + + + + \ No newline at end of file -- 2.18.1