From 416e53d6a9fe3e1f17da67498971f589bb0828c5 Mon Sep 17 00:00:00 2001
From: Falucho <german.faller@pcunix71.fing.edu.uy>
Date: Tue, 25 Jun 2019 02:22:46 -0300
Subject: [PATCH]  JWT, Cookie & Filtros

---
 .../uy/edu/fing/tse/jsf/UserLoginBean.java    | 32 +++++++-----
 .../edu/fing/tse/jsf/security/JwtFilter.java  | 26 +++++++---
 .../fing/tse/jsf/security/LoginFilter.java    | 50 +++++++++++++++++++
 .../edu/fing/tse/jsf/session/SessionBean.java | 46 -----------------
 .../webapp/WEB-INF/templates/template.xhtml   |  3 +-
 .../src/main/webapp/jsf/gestionhechos.xhtml   |  2 +-
 backoffice/src/main/webapp/login.xhtml        |  1 -
 .../main/java/uy/edu/fing/tse/dto/Fact.java   |  4 --
 .../business/security/SecurityBean.java       |  2 +-
 9 files changed, 92 insertions(+), 74 deletions(-)
 create mode 100644 backoffice/src/main/java/uy/edu/fing/tse/jsf/security/LoginFilter.java
 delete mode 100644 backoffice/src/main/java/uy/edu/fing/tse/jsf/session/SessionBean.java

diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/UserLoginBean.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/UserLoginBean.java
index 8a3ae8f..525e65e 100644
--- a/backoffice/src/main/java/uy/edu/fing/tse/jsf/UserLoginBean.java
+++ b/backoffice/src/main/java/uy/edu/fing/tse/jsf/UserLoginBean.java
@@ -1,19 +1,18 @@
 package uy.edu.fing.tse.jsf;
 
+import org.primefaces.PrimeFaces;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import uy.edu.fing.tse.central.business.BusinessLocal;
 import uy.edu.fing.tse.central.business.security.SecurityLocal;
 import uy.edu.fing.tse.dto.Role;
 import uy.edu.fing.tse.dto.UserBO;
-import uy.edu.fing.tse.jsf.session.SessionBean;
 
 import javax.annotation.PostConstruct;
 import javax.ejb.EJB;
 import javax.enterprise.context.RequestScoped;
 import javax.faces.application.FacesMessage;
 import javax.faces.context.FacesContext;
-import javax.inject.Inject;
 import javax.inject.Named;
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.Size;
@@ -37,9 +36,6 @@ public class UserLoginBean implements Serializable {
     @EJB
     private BusinessLocal negocio;
 
-    @Inject
-    private SessionBean session;
-
     private List<Role> roles;
 
     @PostConstruct
@@ -73,14 +69,13 @@ public class UserLoginBean implements Serializable {
         this.repassword = repassword;
     }
 
-    public String login() {
+    public void login() {
         String token = securityLocal.login(user);
 
         if (token != null) {
             addCookieToken(token);
-            session.setToken(token);
-            session.setUser(user);
-            return "jsf/gestionhechos";
+            PrimeFaces.current().executeScript("window.location.href='jsf/gestionhechos.xhtml'");
+            //return "jsf/gestionhechos";
         } else {
             FacesContext.getCurrentInstance().addMessage(
                     null,
@@ -88,10 +83,15 @@ public class UserLoginBean implements Serializable {
                             "Ingreso Incorrecto",
                             "Por favor verificar los datos ingresados"));
         }
-        return "";
     }
 
-    public String register() {
+    public void logout() {
+        removeCookieToken();
+        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
+        PrimeFaces.current().executeScript("window.location.href='jsf/index.xhtml'");
+    }
+
+    public void register() {
         boolean valid = true;
 
         // verificar que sean iguales la pasw, en caso contrario
@@ -100,14 +100,13 @@ public class UserLoginBean implements Serializable {
         //TODO
         if (valid) {
             final var s = securityLocal.register(user);
-            return "jsf/gestionhechos";
+            PrimeFaces.current().executeScript("window.location.href='jsf/gestionhechos.xhtml'");
         } else {
             FacesContext.getCurrentInstance().addMessage(
                     null,
                     new FacesMessage(FacesMessage.SEVERITY_WARN,
                             " Usuario o Password diferentes",
                             "Por favor verificar los datos ingresados"));
-            return "";
         }
     }
 
@@ -119,4 +118,11 @@ public class UserLoginBean implements Serializable {
                 .addResponseCookie("token", URLEncoder.encode(token, StandardCharsets.UTF_8), properties);
     }
 
+    private void removeCookieToken() {
+        final Map<String, Object> properties = new HashMap<>();
+        properties.put("maxAge", 0);
+        properties.put("path", "/");
+        FacesContext.getCurrentInstance().getExternalContext()
+                .addResponseCookie("token", "", properties);
+    }
 }
diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/JwtFilter.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/JwtFilter.java
index b0bc473..bb639f1 100644
--- a/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/JwtFilter.java
+++ b/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/JwtFilter.java
@@ -22,13 +22,7 @@ public class JwtFilter implements javax.servlet.Filter {
         final HttpServletRequest request = (HttpServletRequest) req;
         final HttpServletResponse response = (HttpServletResponse) res;
 
-        Cookie cookieToken = null;
-        for (Cookie cookie : request.getCookies()) {
-            if ("token".equals(cookie.getName())) {
-                cookieToken = cookie;
-                break;
-            }
-        }
+        Cookie cookieToken = findTokenCookie(request);
 
         if (cookieToken == null || cookieToken.getValue() == null) {
             response.setStatus(401);
@@ -41,6 +35,10 @@ public class JwtFilter implements javax.servlet.Filter {
         try {
             final Claims claims = Jwts.parser().setSigningKey("1q2w3e4r5t6y7u8i9o0p").parseClaimsJws(token).getBody();
             request.setAttribute("claims", claims);
+            final var session = request.getSession();
+            session.setAttribute("token", token);
+            session.setAttribute("role", claims.get("role"));
+            session.setAttribute("user", claims.getSubject());
         } catch (final Exception e) {
             response.setStatus(401);
             response.sendRedirect(request.getContextPath() + "/login.xhtml");
@@ -50,6 +48,20 @@ public class JwtFilter implements javax.servlet.Filter {
         chain.doFilter(req, res);
     }
 
+    static Cookie findTokenCookie(final HttpServletRequest request) {
+        Cookie cookieToken = null;
+        final var cookies = request.getCookies();
+        if (cookies != null) {
+            for (Cookie cookie : cookies) {
+                if ("token".equals(cookie.getName())) {
+                    cookieToken = cookie;
+                    break;
+                }
+            }
+        }
+        return cookieToken;
+    }
+
     @Override
     public void destroy() {
     }
diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/LoginFilter.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/LoginFilter.java
new file mode 100644
index 0000000..7fd3082
--- /dev/null
+++ b/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/LoginFilter.java
@@ -0,0 +1,50 @@
+package uy.edu.fing.tse.jsf.security;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+
+import javax.servlet.*;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import static uy.edu.fing.tse.jsf.security.JwtFilter.findTokenCookie;
+
+@WebFilter("/login.xhtml")
+public class LoginFilter implements Filter {
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+    }
+
+    @Override
+    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
+        final HttpServletRequest request = (HttpServletRequest) req;
+        final HttpServletResponse response = (HttpServletResponse) res;
+
+        Cookie cookieToken = findTokenCookie(request);
+
+        if (cookieToken == null || cookieToken.getValue() == null) {
+            chain.doFilter(req, res);
+            return;
+        }
+
+        final var token = cookieToken.getValue();
+
+        try {
+            final Claims claims = Jwts.parser().setSigningKey("1q2w3e4r5t6y7u8i9o0p").parseClaimsJws(token).getBody();
+            response.sendRedirect(request.getContextPath() + "/jsf/gestionhechos.xhtml");
+        } catch (final Exception e) {
+            chain.doFilter(req, res);
+            return;
+        }
+
+        chain.doFilter(req, res);
+    }
+
+    @Override
+    public void destroy() {
+    }
+}
diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/session/SessionBean.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/session/SessionBean.java
deleted file mode 100644
index 54b7c82..0000000
--- a/backoffice/src/main/java/uy/edu/fing/tse/jsf/session/SessionBean.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package uy.edu.fing.tse.jsf.session;
-
-import uy.edu.fing.tse.dto.UserBO;
-
-import javax.enterprise.context.SessionScoped;
-import javax.inject.Named;
-import java.io.Serializable;
-
-@SessionScoped
-@Named("sessionBean")
-public class SessionBean implements Serializable {
-
-    private static final long serialVersionUID = 9062153372176877309L;
-
-    private String token = null;
-
-    private UserBO user = null;
-
-    public String getToken() {
-        return token;
-    }
-
-    public void setToken(String token) {
-        this.token = token;
-    }
-
-    public UserBO getUser() {
-        return user;
-    }
-
-    public void setUser(UserBO user) {
-        this.user = user;
-    }
-
-    public String makeToken() {
-        if (token == null) {
-            return null;
-        }
-        return "Bearer " + token;
-    }
-
-    public void invalidate() {
-        token = null;
-        user = null;
-    }
-}
diff --git a/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml b/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml
index 62700bc..ccb73d8 100644
--- a/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml
+++ b/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml
@@ -34,9 +34,10 @@
     <title>BackOffice - feiknius</title>
 </h:head>
 <h:body>
-
     <header>
         <h1>BackOffice - feiknius</h1>
+        <p:commandButton value="Salir" action="#{userLoginView.logout()}"
+                         rendered="#{session.getAttribute('user')!=null}"/>
     </header>
     <!-- Menús, headers y todo lo que vaya antes del contenido -->
     <p:messages/>
diff --git a/backoffice/src/main/webapp/jsf/gestionhechos.xhtml b/backoffice/src/main/webapp/jsf/gestionhechos.xhtml
index 45ada12..41d6898 100644
--- a/backoffice/src/main/webapp/jsf/gestionhechos.xhtml
+++ b/backoffice/src/main/webapp/jsf/gestionhechos.xhtml
@@ -12,7 +12,7 @@
         <h:form>
             <p:outputPanel style="font-size: 30px;text-align: center">
                 <h:outputText value="Bienvenido "/>
-                <h:outputText value="#{sessionBean.user.mail}"/>
+                <h:outputText value="#{session.getAttribute('user')}"/>
             </p:outputPanel>
 
             <p:dataTable var="hecho" id="dataHecho" value="#{gestionHechos.facts}" widgetVar="NoticiasTable"
diff --git a/backoffice/src/main/webapp/login.xhtml b/backoffice/src/main/webapp/login.xhtml
index 69689b8..29b3ae4 100644
--- a/backoffice/src/main/webapp/login.xhtml
+++ b/backoffice/src/main/webapp/login.xhtml
@@ -31,7 +31,6 @@
                                      value="Login" action="#{userLoginView.login()}"
                                      update="form"/>
                 </f:facet>
-                <h:inputHidden id="token" value="#{sessionBean.token}"/>
             </h:panelGrid>
         </h:form>
     </ui:define>
diff --git a/central-dto/src/main/java/uy/edu/fing/tse/dto/Fact.java b/central-dto/src/main/java/uy/edu/fing/tse/dto/Fact.java
index d2eed68..9927394 100644
--- a/central-dto/src/main/java/uy/edu/fing/tse/dto/Fact.java
+++ b/central-dto/src/main/java/uy/edu/fing/tse/dto/Fact.java
@@ -44,10 +44,6 @@ public final class Fact implements Serializable {
         return actualState;
     }
 
-    public State getActualState2() {
-        return actualState;
-    }
-
     public void setActualState(State actualState) {
         this.actualState = actualState;
     }
diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityBean.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityBean.java
index 37680ea..de35d08 100644
--- a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityBean.java
+++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityBean.java
@@ -58,7 +58,7 @@ public class SecurityBean implements SecurityLocal, SecurityRemote {
         return null;
     }
 
-    private String createJWT(String role, String user) {
+    private String createJWT(String user, String role) {
         // prepare expiration date according to application properties
         Date expDate = new Date();
         Calendar calendar = Calendar.getInstance();
-- 
GitLab