Como fazer login utilizando Form JSF e PrimeFaces no Spring Security
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?