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