Skip to content

Instantly share code, notes, and snippets.

@robsonlira
Last active November 9, 2021 12:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robsonlira/7328bfa6a241cbc9d178458e9ebb9397 to your computer and use it in GitHub Desktop.
Save robsonlira/7328bfa6a241cbc9d178458e9ebb9397 to your computer and use it in GitHub Desktop.
JSF com Rest API
<!DOCTYPE html>
<ui:composition lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:panelGroup layout="block">
<div id="userInfo">
<h:form id="logout_form">
<p>
#{usuarioWebBean.usuario.username} -
<h:commandLink value="Sair" action="#{loginBean.logout}"/>
</p>
</h:form>
</div>
<div id="menuWrap">
<ul id="menuElementsEn">
<li><a href="${ctx}/home.xhtml">Home</a></li>
<li><a href="${ctx}/pages/dashboard/dashboard.xhtml">Dashboard</a></li>
<li><a href="${ctx}/pages/projeto/projeto.xhtml">Projetos</a></li>
<li><a href="${ctx}/pages/usuario/usuario.xhtml">Usuarios</a></li>
<li><a href="${ctx}/pages/issue/issue.xhtml">Issues</a></li>
</ul><!-- menuElements-->
</div><!-- menuWrap-->
</h:panelGroup>
</ui:composition>
@Log
public class JsonUtil implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
@RequestCookieMap
private Map<String, Object> cookieMap;
public HttpHeaders createJsonHeader() {
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON_UTF8);
return header;
}
public HttpHeaders createTokenizedHeader() {
HttpHeaders header = createJsonHeader();
Cookie tokenCookie = (Cookie) cookieMap.get("token");
if (tokenCookie.getValue().isEmpty())
log.info("Atenção! Sem token");
header.add("Authorization", decodeUTF8(tokenCookie.getValue()));
return header;
}
public HttpEntity tokenizedHttpEntityHeader() {
return new HttpEntity(createTokenizedHeader());
}
public <E> HttpEntity<E> tokenizedHttpEntityHeader(E e) {
return new HttpEntity<>(e,createTokenizedHeader());
}
}
@Log
@Getter
@Setter
@Named
@ViewScoped
public class LoginBean implements Serializable {
private static final long serialVersionUID = 1L;
private String login;
private String senha;
private UsuarioWeb usuario = null;
private final LoginDAO loginDAO;
private final UsuarioWebBean usuarioWebBean;
private final UsuarioWebDAO usuarioWebDAO;
private final ExternalContext externalContext;
@Inject
public LoginBean(LoginDAO loginDAO, UsuarioWebBean usuarioWebBean, UsuarioWebDAO usuarioWebDAO, ExternalContext externalContext) {
this.loginDAO = loginDAO;
this.usuarioWebBean = usuarioWebBean;
this.usuarioWebDAO = usuarioWebDAO;
this.externalContext = externalContext;
}
public String entrar() throws UnsupportedEncodingException {
Token token = loginDAO.loginReturningToken(login, senha);
if (token == null) return null;
addTokenAndExpirationTimeToCookies(token.getToken(), token.getExpirationTime().toString());
addTokenToSession(token.getToken());
return "home.xhtml?faces-redirect=true";
}
public String logout() {
removeTokenAndExpirationTimeFromCookies();
return "login.xhtml?faces-redirect=true";
}
private void addTokenAndExpirationTimeToCookies(String token, String expirationTime) {
externalContext.addResponseCookie("token", CustomURLEncoderDecoder.encodeUTF8(token), null);
externalContext.addResponseCookie("expirationTime", expirationTime, null);
}
private void removeTokenAndExpirationTimeFromCookies() {
addTokenAndExpirationTimeToCookies(null, null);
}
}
@Log
public class LoginDAO implements Serializable {
private static final long serialVersionUID = 1L;
private final CustomRestTemplate restTemplate;
private final JsonUtil jsonUtil;
@Inject
public LoginDAO(CustomRestTemplate restTemplate, JsonUtil jsonUtil) {
this.restTemplate = restTemplate;
this.jsonUtil = jsonUtil;
}
@ExceptionHandler
public Token loginReturningToken(String username, String password) {
String loginJson = "{\"email\":" + addQuotes(username) + ",\"senha\":" + addQuotes(password) + "}";
ResponseEntity<String> response = restTemplate.exchange(LOGIN_URL, POST, new HttpEntity<>(loginJson, jsonUtil.createJsonHeader()),
String.class);
HttpHeaders headers = response.getHeaders();
String header = headers.getFirst("Authorization");
String exp = headers.getFirst("Expiration-Time");
if (header != null && header.startsWith("Bearer ")) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
Token token = new Token();
token.setToken(header);
token.setExpirationTime(LocalDateTime.parse(exp, formatter));
return token;
}
return null;
}
@SuppressWarnings("StringBufferReplaceableByString")
private String addQuotes(String value) {
return new StringBuilder(300).append("\"").append(value).append("\"").toString();
}
}
@Log
@WebFilter(urlPatterns = {"/pages/*"}, description = "Session checker filter")
public class LoginFilter implements Filter, Serializable {
@Inject
private TokenUtil tokenUtil;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("doFilter");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (!req.getRequestURI().endsWith("login.xhtml") && !isTokenValid(req)) {
res.sendRedirect(req.getContextPath() + "/login.xhtml");
return;
}
chain.doFilter(req, res);
}
private boolean isTokenValid(HttpServletRequest request) {
log.info("isTokenValid()");
return tokenUtil.isExpirationTimeFromCookieValid(request) &&
!tokenUtil.getTokenFromCookies(request).isEmpty();
}
}
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>javax.faces-api</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet</artifactId>
<version>2.4.5.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>8.0</version>
</dependency>
<dependency>
<groupId>org.primefaces.themes</groupId>
<artifactId>all-themes</artifactId>
<version>1.0.10</version>
</dependency>
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
<scope>provided</scope>
</dependency>
@Log
public class TokenUtil {
public String getTokenFromCookies(HttpServletRequest request) {
if (request.getCookies() == null) return "";
List<Cookie> cookieList = asList(request.getCookies());
return getCookieByKey(cookieList, "token");
}
public boolean isExpirationTimeFromCookieValid(HttpServletRequest request) {
if (request.getCookies() == null) return false;
List<Cookie> cookieList = asList(request.getCookies());
String expirationTime = getCookieByKey(cookieList, "expirationTime");
return validateIfTimeNowIsBeforeTokenExpires(expirationTime);
}
private String getCookieByKey(List<Cookie> cookieList, String key) {
return cookieList.stream()
.filter(cookie -> cookie.getName().equals(key))
.map(Cookie::getValue)
.findFirst()
.orElse("");
}
private boolean validateIfTimeNowIsBeforeTokenExpires(String expirationTime) {
if (expirationTime.isEmpty()) return false;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
LocalDateTime tokenExpirationTime = LocalDateTime.parse(expirationTime, formatter);
return LocalDateTime.now().isBefore(tokenExpirationTime);
}
}
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class UsuarioWeb extends AbstractEntity {
private Long id;
private String username;
private String password;
private String role;
private Boolean enabled;
}
@Log
@Getter
@Setter
@Named
@SessionScoped
public class UsuarioWebBean implements Serializable {
private static final long serialVersionUID = 1L;
private UsuarioWeb usuario = null;
public void loga(UsuarioWeb usuario) {
this.usuario = usuario;
}
public void logout() {
this.usuario = null;
}
public boolean isLogado() {
return this.usuario != null;
}
}
@Log
public class UsuarioWebDAO implements Serializable {
private static final long serialVersionUID = 1L;
private final JsonUtil jsonUtil;
@Inject
public UsuarioWebDAO(JsonUtil jsonUtil) {
this.jsonUtil = jsonUtil;
}
@ExceptionHandler
public UsuarioWeb get() {
log.info("UsuarioWeb get()");
ResponseEntity<UsuarioWeb> exchange = new RestTemplate().exchange(ApiUtil.BASE_URL+"/home/info", GET, jsonUtil.tokenizedHttpEntityHeader(), UsuarioWeb.class);
return exchange.getBody();
}
}
@robsonlira
Copy link
Author

robsonlira commented Nov 9, 2021

Olá estes são fragmentos de código de um projeto de Issue, chamado IssueTracker da TriadWorks
https://github.com/rponte/jsf-issuetracker-project

Originalmente um projeto padrão JSF que foi modifido para ele consumir uma Api Rest , e esta indo tudo bem, me espelhei na serie de vídeos do canal da DevDojo no YT chamado de Mão na Massa, o problema foi que eu cheguei em um ponto que quis colocar o nome do usuário na pagina.
Originalmente ( no projeto anterior ) qdo se faz o login retorna-se o usuario dai fica tranquilo colocar o usuario no Manager Bean chamado UsuarioWebBean porém aqui eu só tenho como retorno após o login o token e este deverá ser enviado para toda e qualquer requisições seguinte, mais existe um endpoint que retorna dados do usuário logado só dar um get em BASE_URL+"/home/info
Então a logica seria após fazer login consumir este endpoint , o problema é que ao fazer o login eu acabei de colocar o token no cookie não sei o motivo que exatamente após fazer isto não consigo recuperar o token , a recuperação do token ocorre sempre na classe JsonUtil mais parece que ( não sei ) se precisa dar um tempo porque logo assim imediatamente após gravar o token não se consegue obte-lo ( é o que parece )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment