· 6 years ago · Oct 07, 2019, 07:26 PM
1package br.com.unimedfortaleza.portal.security;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.Map;
6
7import org.apache.log4j.Logger;
8import org.joda.time.LocalDateTime;
9import org.springframework.beans.factory.annotation.Autowired;
10import org.springframework.beans.factory.annotation.Value;
11import org.springframework.core.ParameterizedTypeReference;
12import org.springframework.http.HttpHeaders;
13import org.springframework.http.HttpMethod;
14import org.springframework.http.MediaType;
15import org.springframework.security.authentication.AuthenticationProvider;
16import org.springframework.security.authentication.AuthenticationServiceException;
17import org.springframework.security.authentication.BadCredentialsException;
18import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
19import org.springframework.security.core.Authentication;
20import org.springframework.security.core.AuthenticationException;
21import org.springframework.security.core.GrantedAuthority;
22import org.springframework.security.core.authority.SimpleGrantedAuthority;
23import org.springframework.security.crypto.codec.Base64;
24import org.springframework.stereotype.Service;
25import org.springframework.util.LinkedMultiValueMap;
26import org.springframework.util.MultiValueMap;
27
28import br.com.unimedfortaleza.portal.excecao.NenhumRegistroEncontradoException;
29import br.com.unimedfortaleza.portal.excecao.RegraNegocioException;
30import br.com.unimedfortaleza.portal.modelo.bean.ContratoBeneficiario;
31import br.com.unimedfortaleza.portal.modelo.bean.Usuario;
32import br.com.unimedfortaleza.portal.modelo.bean.UsuarioBeneficiario;
33import br.com.unimedfortaleza.portal.modelo.bean.UsuarioColaborador;
34import br.com.unimedfortaleza.portal.modelo.bean.UsuarioCooperado;
35import br.com.unimedfortaleza.portal.modelo.bean.UsuarioEmpresa;
36import br.com.unimedfortaleza.portal.modelo.bean.UsuarioPrestador;
37import br.com.unimedfortaleza.portal.modelo.bean.microservicos.AccessToken;
38import br.com.unimedfortaleza.portal.modelo.dao.PrestadorDAO;
39import br.com.unimedfortaleza.portal.modelo.dao.UsuarioDAO;
40import br.com.unimedfortaleza.portal.modelo.enumeration.Papel;
41import br.com.unimedfortaleza.portal.modelo.handler.GlobalExceptionsHandler;
42import br.com.unimedfortaleza.portal.modelo.servico.ServicoGerenciarUsuariosEmpresa;
43import br.com.unimedfortaleza.portal.modelo.servico.ServicoLogSentry;
44import br.com.unimedfortaleza.portal.modelo.servico.ServicoRequisicao;
45import br.com.unimedfortaleza.portal.modelo.servico.ServicoUsuario;
46import br.com.unimedfortaleza.portal.util.UnimedUtil;
47import io.sentry.event.Event.Level;
48
49/**
50 *
51 * @author thaio.fernandes
52 *
53 */
54@Service("servicoAutenticadorCustomizado")
55public class AutenticadorCustomizado implements AuthenticationProvider {
56
57 @Value("${habilitar.portal.microservico}")
58 private Boolean habilitarMicroservico;
59
60 @Value("${url.portal.microservico}")
61 private String url;
62
63 @Value("${client.id.portal.microservico}")
64 private String clientId;
65
66 @Value("${client.secret.portal.microservico}")
67 private String clientSecret;
68
69 @Autowired
70 private UsuarioDAO usuarioDao;
71
72 @Autowired
73 private ServicoUsuario servicoUsuario;
74
75 @Autowired
76 private PrestadorDAO prestadorDao;
77
78 @Autowired
79 private ServicoGerenciarUsuariosEmpresa servicoGerenciarUsuariosEmpresa;
80
81 @Autowired
82 private ServicoLogSentry servicoLogSentry;
83
84 @Autowired
85 private ServicoRequisicao servicoRequisicao;
86
87 /**
88 * Método para consultar se login e senha são válidos
89 *
90 * @param autenticacao
91 * @return Autehntication
92 */
93 @Override
94 @SuppressWarnings("unchecked")
95 public Authentication authenticate(Authentication autenticacao) throws AuthenticationException {
96 AccessToken accessToken = null;
97
98 if (habilitarMicroservico) {
99 try {
100 HttpHeaders httpHeaders = new HttpHeaders();
101 httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
102 String plainClientCredentials = clientId + ":" + clientSecret;
103 String base64ClientCredentials = new String(Base64.encode(plainClientCredentials.getBytes()));
104 httpHeaders.set("Authorization", "Basic " + base64ClientCredentials);
105
106 MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
107 map.add("username", autenticacao.getName().toString());
108 map.add("password", autenticacao.getCredentials().toString());
109 map.add("scope", "webclient");
110 map.add("grant_type", "password");
111
112 ParameterizedTypeReference<AccessToken> responseType = new ParameterizedTypeReference<AccessToken>() {
113 };
114
115 accessToken = servicoRequisicao.executar(url + "/oauth/token", HttpMethod.POST, httpHeaders,
116 responseType, map, null);
117 } catch (Exception e) {
118 Logger logger = Logger.getLogger(GlobalExceptionsHandler.class);
119 logger.error(e.getMessage(), e);
120 servicoLogSentry.logarSentry(e, Level.ERROR, autenticacao);
121 }
122 }
123
124 // Caso seja possível, retirar os zeros
125 String login = UnimedUtil.formatarLogin(autenticacao.getName().toString());
126
127 Map<String, Object> retorno = null;
128 Usuario usuario = null;
129 try {
130 // Autentica usuário e retorna o seu papel
131 retorno = usuarioDao.autentica(login, autenticacao.getCredentials().toString());
132 // verifica se usuario foi autenticado
133 if (Integer.parseInt(retorno.get("p_ok").toString()) != 1) {
134 throw new BadCredentialsException((String) retorno.get("p_mensagem"));
135 }
136 List<String> papeis = (List<String>) retorno.get("p_papeis");
137 // Cria instancia de tipo de usuario para colocar na sessao
138 // Cria lista de permissões
139 List<GrantedAuthority> perfis = new ArrayList<>();
140 for (String papel : papeis) {
141 perfis.add(new SimpleGrantedAuthority(papel));
142 }
143 // Resolve qual o tipo de usuário vai para sessão
144 Papel papelPrincipal = Papel.valueOf(papeis.get(0));
145
146 switch (papelPrincipal) {
147 case CLIENTE:
148 usuario = new UsuarioBeneficiario(login, autenticacao.getCredentials(), perfis);
149 break;
150 case EMPRESA:
151 usuario = new UsuarioEmpresa(login, autenticacao.getCredentials(), perfis);
152 break;
153 case GRUPO:
154 usuario = new UsuarioEmpresa(login, autenticacao.getCredentials(), perfis);
155 break;
156 case COOPERADO:
157 boolean necessarioAtualizacao = false;
158
159 Map<String, Object> params = prestadorDao.existeNecessidadeAtualizacaoEndereco(login);
160
161 if (params.get("p_ok") == null || (Integer) params.get("p_ok") != 1)
162 necessarioAtualizacao = true;
163
164 usuario = new UsuarioCooperado(login, autenticacao.getCredentials(), perfis, necessarioAtualizacao);
165 break;
166 case PRESTADOR:
167 usuario = new UsuarioPrestador(login, autenticacao.getCredentials(), perfis);
168 break;
169 case COLABORADOR:
170 usuario = new UsuarioColaborador(login, autenticacao.getCredentials(), perfis);
171 break;
172 default:
173 break;
174 }
175
176 // Seta data do último acesso caso não seja primeiro acesso
177 if (retorno.get("p_data_ultimo_acesso") != null) {
178 usuario.setDataUltimoAcesso((LocalDateTime) retorno.get("p_data_ultimo_acesso"));
179 }
180
181 // popula o email
182 servicoUsuario.popularEmailBeneficiario(usuario);
183 usuario.setExibeTutorial(servicoUsuario.exibeTutorial(usuario));
184 } catch (BadCredentialsException e) {
185 throw e;
186 } catch (Exception e) {
187 servicoLogSentry.logarSentry(e, Level.ERROR, retorno);
188 throw new AuthenticationServiceException("Falha ao autenticar usuário. Tente novamente mais tarde.", e);
189 }
190 try {
191 // ########### CLIENTE
192 if (usuario.getAuthorities().contains(new SimpleGrantedAuthority(Papel.CLIENTE.toString()))) {
193
194 // Recupera lista de beneficiarios
195 List<ContratoBeneficiario> contratosBenef = null;
196 contratosBenef = servicoUsuario.selecionarContratos((UsuarioBeneficiario) usuario);
197 ((UsuarioBeneficiario) usuario).setContratosBeneficiarioNaoSelecionados(contratosBenef);
198
199 usuario.setContatos(usuarioDao.selecionarContatosUsuario(usuario));
200 }
201 // ########### CLIENTE PJ
202 else if (usuario.getAuthorities().contains(new SimpleGrantedAuthority(Papel.CLIENTE_PJ.toString()))) {
203 // Caso seja grupo
204 if (usuario.getAuthorities().contains(new SimpleGrantedAuthority(Papel.GRUPO.toString()))) {
205 servicoUsuario.recuperarDadosGrupo((UsuarioEmpresa) usuario);
206 }
207 // Caso seja empresa
208 else {
209 UsuarioEmpresa usuarioRetorno = servicoGerenciarUsuariosEmpresa
210 .recuperarDadosUsuarioEmpresa(usuario.getPrincipal().toString());
211
212 ((UsuarioEmpresa) usuario).setNome(usuarioRetorno.getNome());
213 ((UsuarioEmpresa) usuario).setCpf(usuarioRetorno.getCpf());
214 ((UsuarioEmpresa) usuario).setEmpresasNaoSelecionadas(usuarioRetorno.getEmpresasNaoSelecionadas());
215 usuario.setContatos(usuarioDao.selecionarContatosUsuario(usuario));
216 }
217 }
218 // ########### COOPERADO
219 else if (usuario.getAuthorities().contains(new SimpleGrantedAuthority(Papel.COOPERADO.toString()))) {
220
221 // Seta os dados do cooperado no usuário da sessão
222 servicoUsuario.recuperarDadosCooperado((UsuarioCooperado) usuario);
223 usuario.setContatos(usuarioDao.selecionarContatosUsuario(usuario));
224 }
225 // ########### PRESTADOR
226 else if (usuario.getAuthorities().contains(new SimpleGrantedAuthority(Papel.PRESTADOR.toString()))) {
227 // Seta os dados do cooperado no usuário da sessão
228 servicoUsuario.recuperarDadosPrestador((UsuarioPrestador) usuario);
229
230 }
231 // ########### COLABORADOR
232 else if (usuario.getAuthorities().contains(new SimpleGrantedAuthority(Papel.COLABORADOR.toString()))) {
233 // Seta os dados do colaborador no usuário da sessão
234 servicoUsuario.recuperarDadosColaborador((UsuarioColaborador) usuario);
235
236 }
237
238 } catch (RegraNegocioException | NenhumRegistroEncontradoException e) {
239 throw new AuthenticationServiceException(e.getMessage(), e);
240 } catch (Exception e) {
241 Logger logger = Logger.getLogger(GlobalExceptionsHandler.class);
242 logger.error(e.getMessage(), e);
243 servicoLogSentry.logarSentry(e, Level.ERROR, usuario);
244 throw new AuthenticationServiceException("Erro ao autenticar.", e);
245 }
246
247 if (accessToken != null) {
248 usuario.setAccessToken(accessToken);
249 }
250
251 return usuario;
252 }
253
254 /**
255 * Verifica se classe passada é do tipo suportado pelo spring security
256 *
257 * @param classe
258 * @return boolean
259 */
260 @Override
261 public boolean supports(Class<?> classe) {
262 return UsernamePasswordAuthenticationToken.class.isAssignableFrom(classe);
263 }
264}