AuthProvider.java 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package es.uv.saic.service;
  2. import java.time.LocalDateTime;
  3. import java.util.ArrayList;
  4. import java.util.Hashtable;
  5. import java.util.List;
  6. import java.util.stream.Collectors;
  7. import javax.naming.Context;
  8. import javax.naming.NamingEnumeration;
  9. import javax.naming.NamingException;
  10. import javax.naming.directory.Attribute;
  11. import javax.naming.directory.Attributes;
  12. import javax.naming.directory.DirContext;
  13. import javax.naming.directory.InitialDirContext;
  14. import javax.naming.directory.SearchControls;
  15. import javax.naming.directory.SearchResult;
  16. import org.slf4j.Logger;
  17. import org.slf4j.LoggerFactory;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.security.authentication.AuthenticationProvider;
  20. import org.springframework.security.authentication.AuthenticationServiceException;
  21. import org.springframework.security.authentication.BadCredentialsException;
  22. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  23. import org.springframework.security.core.Authentication;
  24. import org.springframework.security.core.AuthenticationException;
  25. import org.springframework.security.core.authority.SimpleGrantedAuthority;
  26. import org.springframework.stereotype.Component;
  27. import es.uv.saic.SaicApplication;
  28. import es.uv.saic.shared.domain.Usuari;
  29. @Component
  30. public class AuthProvider implements AuthenticationProvider {
  31. @Autowired
  32. private UsuariService us;
  33. @Autowired
  34. private UsuarisRolService urs;
  35. private static final Logger logger = LoggerFactory.getLogger(SaicApplication.class);
  36. @Override
  37. public Authentication authenticate(Authentication auth) throws AuthenticationException {
  38. String username = auth.getName().toLowerCase().trim();
  39. String password = auth.getCredentials().toString();
  40. List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
  41. Usuari u = this.us.findByUsername(username);
  42. if(u != null) {
  43. u.setGranted(this.urs.isGrantedUser(u));
  44. u.setAdmin(this.urs.isAdminUser(u));
  45. u.setDataTest(this.urs.isDataTestUser(u));
  46. boolean vigent = this.us.hasActiveRol(u);
  47. if(!u.getLdap() && vigent) {
  48. if (u.getUsuari().equals(username) && u.getClau().equals(password)) {
  49. logger.info("Autenticación LOCAL correcta: "+username);
  50. List<Integer> ids = u.getUsuarisRols().stream().map(ur -> ur.getRol().getIdRol()).collect(Collectors.toList());
  51. for (String permission : this.us.getPermisosRoles(ids)) {
  52. authorities.add(new SimpleGrantedAuthority("ROLE_" + permission.toUpperCase()));
  53. }
  54. UsernamePasswordAuthenticationToken authUser = new UsernamePasswordAuthenticationToken(u, password, authorities);
  55. authUser.setDetails(u);
  56. return authUser ;
  57. }
  58. else {
  59. logger.info("Error de autenticación LOCAL ["+username+"]: el usuario o la contraseña no coinciden");
  60. throw new BadCredentialsException("Error de autenticación LOCAL ["+username+"]: el usuario o la contraseña no coinciden");
  61. }
  62. }
  63. else if(vigent) {
  64. Hashtable<String, String> env = new Hashtable<String, String>();
  65. env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
  66. env.put(Context.PROVIDER_URL, "ldap://ldap.uv.es/");
  67. env.put(Context.SECURITY_AUTHENTICATION, "simple");
  68. env.put(Context.SECURITY_PRINCIPAL, "uid=" + username.toLowerCase().trim() + ", dc=uv, dc=es ");
  69. env.put(Context.SECURITY_CREDENTIALS, password);
  70. try {
  71. DirContext dc = new InitialDirContext(env);
  72. String base = "dc=uv,dc=es";
  73. String filter = "(&(uid=" + username + "))";
  74. int state = 0;
  75. SearchControls ctls = new SearchControls();
  76. ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
  77. ctls.setReturningAttributes(new String[] { "uid" });
  78. NamingEnumeration<SearchResult> resultEnum = dc.search(base, filter, ctls);
  79. while (resultEnum.hasMore() && state < 2) {
  80. SearchResult result = resultEnum.next();
  81. Attributes attrs = result.getAttributes();
  82. if (attrs.size() != 1) {
  83. logger.info("Error de autenticación LDAP ["+username+"]: el usuario o la contraseña no coinciden");
  84. throw new BadCredentialsException("Error de autenticación LDAP ["+username+"]: el usuario o la contraseña no coinciden");
  85. }
  86. NamingEnumeration<?> e = attrs.getAll();
  87. while (e.hasMore()) {
  88. Attribute attr = (Attribute) e.next();
  89. if (!((String) attr.get()).equals(username)) {
  90. logger.info("Error de autenticación LDAP ["+username+"]: el usuario no coincide con el devuelto por el servidor");
  91. throw new BadCredentialsException("Error de autenticación LDAP ["+username+"]: el usuario no coincide con el devuelto por el servidor");
  92. }
  93. }
  94. state++;
  95. }
  96. dc.close();
  97. if (state < 1 || state > 1) {
  98. logger.info("Error de autenticación LDAP ["+username+"]: -> el servidor LDAP ha devuelto un estado incorrecto.");
  99. throw new BadCredentialsException("Error de autenticación LDAP ["+username+"]: -> el servidor LDAP ha devuelto un estado incorrecto.");
  100. }
  101. logger.info("Autenticación LDAP correcta: " + u.getUsuari());
  102. u.setDataUltim(LocalDateTime.now());
  103. this.us.save(u);
  104. List<Integer> ids = u.getUsuarisRols().stream().map(ur -> ur.getRol().getIdRol()).collect(Collectors.toList());
  105. for (String permission : this.us.getPermisosRoles(ids)) {
  106. authorities.add(new SimpleGrantedAuthority("ROLE_" + permission.toUpperCase()));
  107. }
  108. UsernamePasswordAuthenticationToken authUser = new UsernamePasswordAuthenticationToken(u, password, authorities);
  109. authUser.setDetails(u);
  110. return authUser ;
  111. }
  112. catch (NamingException ex) {
  113. logger.info("Error de autenticación ["+username+"]: " + ex.getMessage());
  114. throw new AuthenticationServiceException("Error de autenticación ["+username+"]: " + ex.getMessage());
  115. }
  116. }
  117. }
  118. throw new BadCredentialsException("Error general en el sistema de autenticación");
  119. }
  120. @Override
  121. public boolean supports(Class<?> auth) {
  122. return auth.equals(UsernamePasswordAuthenticationToken.class);
  123. }
  124. }