Como fazer login utilizando Form JSF e PrimeFaces no Spring Security
Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!
Como fazer login utilizando Form JSF e PrimeFaces no Spring Security
template.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:pe="http://primefaces.org/ui/extensions"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<h:outputStylesheet library="webjars"
name="primeflex/3.0.1/primeflex.min.css" />
</h:head>
<h:body>
<pe:layout id="fullPage" stateCookie="true" widgetVar="fpLayoutWidget">
<pe:layoutPane position="center" styleClassContent="conteudoPanel" spacingOpen="1">
<!-- TOPO DA PAGINA -->
<pe:layoutPane size="15%" position="north" styleClassContent="conteudoPanel" resizable="false" closable="false" spacingOpen="1">
<p:commandButton type="button" icon="fa fa-fw fa-windows" onclick="PF('fpLayoutWidget').toggle('east')" style="position:absolute;right:10px;top:10px;" rendered="#{usuarioLogado != null}" />
<ui:include src="header.xhtml" />
</pe:layoutPane>
<!-- CENTRO DA PAGINA -->
<pe:layoutPane size="70%" position="center" styleClassContent="conteudoPanel" spacingOpen="1">
<ui:insert name="centerContent">
Parte Central - Aonde vai a pagina xhtml a ser inserida
</ui:insert>
</pe:layoutPane>
<!-- RODAPÉ DA PAGINA -->
<pe:layoutPane size="15%" position="south" styleClassContent="conteudoPanel" resizable="false" closable="false" spacingOpen="1">
Rodapé
</pe:layoutPane>
</pe:layoutPane>
<!-- MENU DIREITO DA PAGINA -->
<pe:layoutPane id="layoutPaneEast" position="east" styleClassContent="conteudoPanel" resizable="false" spacingOpen="1" spacingClosed="0">
Painel à direita<br />
</pe:layoutPane>
</pe:layout>
</h:body>
</html>login.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:pe="http://primefaces.org/ui/extensions"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
template="../../templates/template.xhtml">
<ui:define name="centerContent">
<script src='https://www.google.com/recaptcha/api.js'></script>
<div class="flex align-items-center md:justify-content-center"
style="min-height: 100%;">
<h:form id="login" prependId="false">
<p:growl showDetail="true" showSummary="true" globalOnly="true"
keepAlive="true" />
<!-- <p:messages showDetail="true" showSummary="true" globalOnly="true" -->
<!-- style="width:25rem;" /> -->
<p:fieldset legend="Login">
<h:panelGrid columns="3">
<p:outputLabel value="Nickname:" for="nickname" />
<p:inputText id="nickname" value="#{loginBean.usuario.nickname}"
required="true" style="width:10rem;" />
<p:message for="nickname" id="messageNickname" />
<p:outputLabel value="Senha:" for="senha" />
<p:password id="senha" value="#{loginBean.usuario.senha}"
toggleMask="true" redisplay="true" feedback="true" inline="true"
required="true" style="width:10rem;" />
<p:message for="senha" id="messageSenha" />
<!-- <p:outputLabel value="Captcha:" for="capthca" /> -->
<!-- <p:captcha id="captcha" language="pt-BR" label="Captcha" -->
<!-- rendered="true" /> -->
<!-- <p:message for="capthca" id="messageCapthca" /> -->
<p:commandButton value="Efetue Login" type ="submit"
action="#{root}/login/process" update="@form" process="@form" />
</h:panelGrid>
</p:fieldset>
</h:form>
</div>
</ui:define>
</ui:composition>
LoginController.class
package br.com.coletadedados.controller;
import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.annotation.RequestScope;
import br.com.coletadedados.controller.api.dto.request.UsuarioDTO;
import br.com.coletadedados.controller.dto.LoginDTO;
import br.com.coletadedados.service.UsuarioService;
import br.com.coletadedados.util.Mensagem;
@Controller(value = "loginBean")
@RequestScope
@RequestMapping("/login")
public class LoginController implements Serializable {
private static final long serialVersionUID = 6273675035903617849L;
private LoginDTO usuario = new LoginDTO();
@Autowired
private UsuarioService loginService;
@GetMapping
public String getPageLogin() {
return "/pages/login/login.jsf";
}
@RequestMapping(value = "/process", method = RequestMethod.POST)
public void efetuaLogin(HttpServletRequest req, @RequestBody LoginDTO usuario) {
System.out.println(usuario.getNickname());
System.out.println(usuario.getSenha());
try {
loginService.autenticar(req, usuario);
Mensagem.mensagemInformacao(null, SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString(), "Login:");
} catch (Exception e) {
Mensagem.mensagemErro(null, e.getMessage(), "Erro ao efetuar login:");
e.printStackTrace();
}
}
public LoginDTO getUsuario() {
return usuario;
}
public void setUsuario(LoginDTO usuario) {
this.usuario = usuario;
}
}UsuarioService.class
package br.com.coletadedados.service;
import java.util.Optional;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.stereotype.Service;
import br.com.coletadedados.config.spring.autenticacao.CustomAuthenticationProvider;
import br.com.coletadedados.controller.api.dto.request.UsuarioDTO;
import br.com.coletadedados.controller.dto.LoginDTO;
import br.com.coletadedados.model.Usuario;
import br.com.coletadedados.repository.UsuarioRepository;
import br.com.coletadedados.service.singleton.LoogerService;
@Service("usuarioService")
public class UsuarioService {
@Autowired
private UsuarioRepository usuarioRepository;
@Autowired
private LoogerService logger;
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
public void autenticar(HttpServletRequest req, LoginDTO usuario) throws Exception {
try {
UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(usuario.getNickname(),
usuario.getSenha());
Authentication auth = this.customAuthenticationProvider.authenticate(authReq);
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(auth);
HttpSession session = req.getSession(true);
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, sc);
} catch (Exception e) {
throw e;
}
}
}
SecurityConfiguration.class
package br.com.coletadedados.config.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import br.com.coletadedados.config.spring.autenticacao.AuthenticationFailureHandlerCuston;
import br.com.coletadedados.config.spring.autenticacao.CustomAuthenticationProvider;
import br.com.coletadedados.config.spring.filter.EncodingFilter;
@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
//Configuracoes de autenticacao
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
//Configuracoes de autorizacao
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("nickname")
.passwordParameter("senha")
.loginProcessingUrl("/login/process")
.defaultSuccessUrl("/painelcontrol",true)
.failureForwardUrl("/login?error")
.failureHandler(authenticationFailureHandlerCuston)
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.deleteCookies("auth_code", "JSESSIONID", "remember-me")
.clearAuthentication(true)
.invalidateHttpSession(true)
.permitAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.exceptionHandling().accessDeniedPage("/403");
}
//Configuracoes de recursos estaticos(js, css, imagens, etc.)
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/pages/login/login.jsf","/**.html", "/**.xhtml", "/**.jsf", "/webjars/**", "/resources/**", "/javax.faces.resource/**");
}
}
CustomAuthenticationProvider.class
package br.com.coletadedados.config.spring.autenticacao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import br.com.coletadedados.model.Usuario;
import br.com.coletadedados.repository.UsuarioRepository;
@Configuration("customAuthenticationProvider")
public class CustomAuthenticationProvider implements AuthenticationProvider{
@Autowired
private UsuarioRepository usuarioRepository;
// @Autowired
// private UsuarioService usuarioService;
private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
System.out.println("Entrou no CustomAuthenticationProvider");
UsernamePasswordAuthenticationToken userToken = (UsernamePasswordAuthenticationToken) authentication;
String loginFornecido = userToken.getName();
String senhaFornecida = (String) userToken.getCredentials();
verificarPreenchimentoLoginESenha(loginFornecido, senhaFornecida);
// Usuario details = usuarioService.obterUsuario(loginFornecido);
Usuario details = usuarioRepository.findByNickname(loginFornecido).orElse(null);
verificarLoginESenha(senhaFornecida, details);
return new UsernamePasswordAuthenticationToken(details, senhaFornecida, details.getAuthorities());
}
private void verificarLoginESenha(String senhaFornecida, Usuario details) {
if (details == null) {
throw new BadCredentialsException("Login e/ou senha inválidos");
}
if (!passwordEncoder.matches(senhaFornecida, details.getPassword())) {
throw new BadCredentialsException("Login e/ou senha inválidos");
}
}
private void verificarPreenchimentoLoginESenha(String loginFornecido, String senhaFornecida) {
if (loginFornecido == null || loginFornecido.trim().equals("")
|| senhaFornecida == null
|| senhaFornecida.trim().equals(""))
throw new BadCredentialsException(
"Os campos login e senha são obrigatórios");
}
@SuppressWarnings("rawtypes")
@Override
public boolean supports(Class authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
}
Alguém consegue me ajudar?