Se agrega bitacora y eventos de login, se baja el tiempo de logout por...

Se agrega bitacora y eventos de login, se baja el tiempo de logout por inactiviadad y se bloquean varias sesiones activas simultaneas
parent 391436ca
...@@ -42,7 +42,12 @@ ...@@ -42,7 +42,12 @@
Usuario y/o contraseña no vlidos. Usuario y/o contraseña no vlidos.
</label> </label>
</c:if> </c:if>
</div> <c:if test="${param.login_error eq 2}">
<label class="error">
El usuario ya cuenta con una sesi&oacute;n activa.
</label>
</c:if>
</div>
<div class="form-group"> <div class="form-group">
<input id="loginEmail" type="text" name="j_username" <input id="loginEmail" type="text" name="j_username"
placeholder='Usuario' class="form-control"> placeholder='Usuario' class="form-control">
......
...@@ -3,7 +3,10 @@ package com.mx.dla.admin.actions; ...@@ -3,7 +3,10 @@ package com.mx.dla.admin.actions;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.ibatis.executor.result.ResultMapException; import org.apache.ibatis.executor.result.ResultMapException;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
...@@ -42,10 +45,21 @@ public class InicioAction extends BaseContratoAction { ...@@ -42,10 +45,21 @@ public class InicioAction extends BaseContratoAction {
String retorno = SUCCESS; String retorno = SUCCESS;
try { try {
Authentication autenticacion = SecurityContextHolder.getContext().getAuthentication(); Authentication autenticacion = SecurityContextHolder.getContext().getAuthentication();
HttpServletRequest request = ServletActionContext.getRequest();
// Obtener la direccin IP del cliente
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null || ipAddress.isEmpty()) {
ipAddress = request.getRemoteAddr();
}
String userAgent = request.getHeader("User-Agent");
UsuarioDTO usuario = usuarioDAO.obtenerUsuario(autenticacion.getName()); UsuarioDTO usuario = usuarioDAO.obtenerUsuario(autenticacion.getName());
ActionContext.getContext().getSession().remove("pmn"); ActionContext.getContext().getSession().remove("pmn");
ActionContext.getContext().getSession().remove("pmnReturn"); ActionContext.getContext().getSession().remove("pmnReturn");
getSession().put("ipAdress",ipAddress);
getSession().put("userAgent",userAgent);
if (!this.getPmn().equals("0")) if (!this.getPmn().equals("0"))
retorno = "menu_" + this.getPmn(); retorno = "menu_" + this.getPmn();
......
package com.mx.dla.configuration;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Objects;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Component;
import com.mx.dla.admin.daos.UsuarioDAO;
@Component
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
protected Logger logger = LoggerFactory.getLogger("app");
@Autowired
private UsuarioDAO usuarioDAO;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
logger.info("Login failed: " + exception.getMessage() + " at " + LocalDateTime.now());
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null || ipAddress.isEmpty()) {
ipAddress = request.getRemoteAddr();
}
String username = request.getParameter("username");
String userAgent = request.getHeader("User-Agent");
if (exception.getClass().isAssignableFrom(DisabledException.class) ||
exception.getClass().isAssignableFrom(SessionAuthenticationException.class)) {
super.setDefaultFailureUrl("/index.jsp?login_error=2");
} else {
super.setDefaultFailureUrl("/index.jsp?login_error=1");
}
if(Objects.nonNull(username)) {
usuarioDAO.insertaBitacora("LogIn Fallido", username, ipAddress, userAgent);
} else {
usuarioDAO.insertaBitacora("LogIn Fallido", "NO USER", ipAddress, userAgent);
}
super.onAuthenticationFailure(request, response, exception);
}
}
package com.mx.dla.configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import com.mx.dla.admin.daos.UsuarioDAO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
@Component
public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired
private UsuarioDAO usuarioDAO;
protected Logger logger = LoggerFactory.getLogger("app");
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
System.out.println("Login successful: " + authentication.getName() + " at " + LocalDateTime.now());
usuarioDAO.actualizaEstadoSesion(0, authentication.getName());
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null || ipAddress.isEmpty()) {
ipAddress = request.getRemoteAddr();
}
String userAgent = request.getHeader("User-Agent");
usuarioDAO.insertaBitacora("LogIn Exitoso", authentication.getName(), ipAddress, userAgent);
getRedirectStrategy().sendRedirect(request, response, "/inicio.action");
}
}
package com.mx.dla.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import com.mx.dla.admin.daos.UsuarioDAO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
@Component
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {
@Autowired
private UsuarioDAO usuarioDAO;
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
// Log en la consola
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null || ipAddress.isEmpty()) {
ipAddress = request.getRemoteAddr();
}
String userAgent = request.getHeader("User-Agent");
if (authentication != null) {
System.out.println("Logout successful: " + authentication.getName() + " at " + LocalDateTime.now());
usuarioDAO.actualizaEstadoSesion(1, authentication.getName());
usuarioDAO.insertaBitacora("LogOut Exitoso", authentication.getName(), ipAddress, userAgent);
}
// Redirigir al usuario a la pgina de login
response.sendRedirect("/dla/index.jsp");
}
}
package com.mx.dla.configuration;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.mx.dla.admin.daos.UsuarioDAO;
import com.mx.dla.admin.dtos.UsuarioDTO;
@Component
@WebListener
public class SessionListener implements HttpSessionListener {
private UsuarioDAO usuarioDAO;
protected Logger logger = LoggerFactory.getLogger("app");
@Override
public void sessionCreated(HttpSessionEvent event) {
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
ServletContext servletContext = event.getSession().getServletContext();
usuarioDAO = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
.getBean(UsuarioDAO.class);
UsuarioDTO usuario = (UsuarioDTO) event.getSession().getAttribute("usuario");
if (usuario != null) {
String ipAdress = event.getSession().getAttribute("ipAdress").toString();
String userAgent = event.getSession().getAttribute("userAgent").toString();
System.out.println("Sesin destruida: " + usuario.getExpediente());
usuarioDAO.actualizaEstadoSesion(1, usuario.getExpediente());
usuarioDAO.insertaBitacora("LogOut Exitoso Destroy", usuario.getExpediente(), ipAdress, userAgent);
}
event.getSession().invalidate();
}
}
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security" <beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/security http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security/spring-security-3.1.xsd"> http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/" security='none' /> <http pattern="/" security='none' />
<http auto-config="true" use-expressions="true"> <http auto-config="true" use-expressions="true">
<intercept-url pattern="/css/**" access="permitAll" /> <intercept-url pattern="/css/**" access="permitAll" />
<intercept-url pattern="/design/**" access="permitAll" /> <intercept-url pattern="/design/**" access="permitAll" />
<intercept-url pattern="/images/**" access="permitAll" /> <intercept-url pattern="/images/**" access="permitAll" />
<intercept-url pattern="/js/**" access="permitAll" /> <intercept-url pattern="/js/**" access="permitAll" />
<intercept-url pattern="/index.jsp**" access="permitAll" />
<intercept-url pattern="/jsp/**" access="isAuthenticated()" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<intercept-url pattern="/index.jsp**" access="permitAll" /> <form-login login-page="/index.jsp"
default-target-url="/inicio.action"
always-use-default-target="true"
authentication-failure-url="/index.jsp?login_error=1"
authentication-success-handler-ref="customAuthenticationSuccessHandler"
authentication-failure-handler-ref="customAuthenticationFailureHandler" />
<logout logout-url="/j_spring_security_logout"
success-handler-ref="customLogoutSuccessHandler" delete-cookies="JSESSIONID" invalidate-session="true"/>
</http>
<!-- Para ver los jsp's es necesario estar logueado --> <authentication-manager alias="authenticationManager">
<intercept-url pattern="/jsp/**" access="isAuthenticated()" /> <authentication-provider>
<jdbc-user-service data-source-ref="dsDLA"
<intercept-url pattern="/**" access="isAuthenticated()" /> users-by-username-query="
<!-- <intercept-url pattern="/**" access="permitAll" /> --> select
EXPEDIENTE as username,
PASSWORD as password,
B_USUARIO_LOGUEADO as enabled
from
DLA_C_USUARIO
where
EXPEDIENTE = ?"
authorities-by-username-query="
select
usr.EXPEDIENTE as expediente,
per.DESC_PERFIL as perfil
from
DLA_C_USUARIO usr,
DLA_C_USUARIO_PERFIL usrper,
DLA_C_PERFIL per
where
usr.EXPEDIENTE = usrper.EXPEDIENTE
AND usrper.ID_PERFIL = per.ID_PERFIL
AND usr.EXPEDIENTE = ?" />
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
<form-login login-page="/index.jsp" default-target-url="/inicio.action" <!-- Beans de los manejadores personalizados -->
always-use-default-target="true" authentication-failure-url="/index.jsp?login_error=1" /> <beans:bean id="customAuthenticationSuccessHandler" class="com.mx.dla.configuration.CustomAuthenticationSuccessHandler" />
</http> <beans:bean id="customAuthenticationFailureHandler" class="com.mx.dla.configuration.CustomAuthenticationFailureHandler" />
<beans:bean id="customLogoutSuccessHandler" class="com.mx.dla.configuration.CustomLogoutSuccessHandler" />
<authentication-manager alias="authenticationManager"> </beans:beans>
<authentication-provider>
<!-- data-source-ref definido en spring-datasource.xml -->
<jdbc-user-service data-source-ref="dsDLA"
users-by-username-query="
select
EXPEDIENTE as username,
PASSWORD as password,
1 as enabled
from
DLA_C_USUARIO
where
EXPEDIENTE = ?"
authorities-by-username-query="
select
usr.EXPEDIENTE as expediente,
per.DESC_PERFIL as perfil
from
DLA_C_USUARIO usr,
DLA_C_USUARIO_PERFIL usrper,
DLA_C_PERFIL per
where
usr.EXPEDIENTE = usrper.EXPEDIENTE
AND usrper.ID_PERFIL = per.ID_PERFIL
AND usr.EXPEDIENTE = ?" />
<!-- salt-source user-property se toma como llave para el descifrado <password-encoder
hash="sha"> <salt-source user-property="username" /> </password-encoder> -->
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
</beans:beans>
\ No newline at end of file
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
<!-- Session --> <!-- Session -->
<session-config> <session-config>
<session-timeout>30</session-timeout> <session-timeout>3</session-timeout>
</session-config> </session-config>
<jsp-config> <jsp-config>
......
...@@ -22,17 +22,8 @@ ...@@ -22,17 +22,8 @@
<link rel="stylesheet" href="${contextPath}/design/css/general.css"> <link rel="stylesheet" href="${contextPath}/design/css/general.css">
<link rel="stylesheet" href="${contextPath}/design/css/theme.css" class="style-theme"> <link rel="stylesheet" href="${contextPath}/design/css/theme.css" class="style-theme">
<!--[if lt IE 9]>
<script src="${contextPath}/design/js/basic/respond.min.js"></script>
<script src="${contextPath}/design/js/basic/html5shiv.min.js"></script>
<![endif]-->
</head> </head>
<body class="login-bg"> <body class="login-bg">
<!--[if lt IE 9]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<!--SECTION--> <!--SECTION-->
<section class="l-main-container"> <section class="l-main-container">
<!--Main Content--> <!--Main Content-->
...@@ -51,6 +42,11 @@ ...@@ -51,6 +42,11 @@
Usuario y/o contrase&ntilde;a no vlidos. Usuario y/o contrase&ntilde;a no vlidos.
</label> </label>
</c:if> </c:if>
<c:if test="${param.login_error eq 2}">
<label class="error">
El usuario ya cuenta con una sesi&oacute;n activa.
</label>
</c:if>
</div> </div>
<div class="form-group"> <div class="form-group">
<input id="loginEmail" type="text" name="j_username" <input id="loginEmail" type="text" name="j_username"
...@@ -79,20 +75,6 @@ ...@@ -79,20 +75,6 @@
<script src="${contextPath}/design/js/shared/jquery.asonWidget.js"></script> <script src="${contextPath}/design/js/shared/jquery.asonWidget.js"></script>
<script src="${contextPath}/design/js/plugins/plugins.js"></script> <script src="${contextPath}/design/js/plugins/plugins.js"></script>
<script src="${contextPath}/design/js/general.js"></script> <script src="${contextPath}/design/js/general.js"></script>
<!-- Semi general-->
<!-- <script type="text/javascript">
var paceSemiGeneral = { restartOnPushState: false };
if (typeof paceSpecific != 'undefined'){
var paceOptions = $.extend( {}, paceSemiGeneral, paceSpecific );
paceOptions = paceOptions;
}else{
paceOptions = paceSemiGeneral;
}
</script> -->
<!--
<script src="${contextPath}/design/js/plugins/pageprogressbar/pace.min.js"></script>
-->
<!-- Specific--> <!-- Specific-->
<script src="${contextPath}/design/js/plugins/forms/validation/jquery.validate.min.js"></script> <script src="${contextPath}/design/js/plugins/forms/validation/jquery.validate.min.js"></script>
...@@ -107,73 +89,4 @@ ...@@ -107,73 +89,4 @@
</script> </script>
</body> </body>
</html> </html>
\ No newline at end of file
<%--
<script>
function fValidarForma(pobForma) {
var login = pobForma.j_username.value;
var pass = pobForma.j_password.value;
if (login.length == 0) {
$('#pMensajeError').html('<fmt:message key="error.003"/>');
} else if (pass.length == 0) {
$('#pMensajeError').html('<fmt:message key="error.004"/>');
} else {
var cadSinEsp = /[^A-Za-z0-9$]/;
var errorMessage = '<fmt:message key="error.005"/>: ';
if (cadSinEsp.test(login)) {
$('#pMensajeError')
.html(
errorMessage
+ '\"<fmt:message key="gral.login.usuario"/>\"');
} else if (cadSinEsp.test(pass)) {
$('#pMensajeError')
.html(
errorMessage
+ '\"<fmt:message key="gral.login.password"/>\"');
} else {
pobForma.submit();
}
}
return false;
}
</script>
<form action="<c:url value='j_spring_security_check'/>" method="post"
onSubmit="return fValidarForma(document.forms[0])">
<table class="tbLogin">
<tr>
<td class="clInputLabel"><fmt:message key="gral.login.usuario" />:</td>
<td class="clInputElement"><input class="login" type="text"
name="j_username" /></td>
</tr>
<tr>
<td class="clInputLabel"><fmt:message key="gral.login.password" />:</td>
<td class="clInputElement"><input class="login" type="password"
name="j_password" />
</tr>
<tr>
<td colspan="2" align="center" height="30"><input
class="clButtonActive" type="submit"
value='<fmt:message key="gral.login.ingresar"/>' /></td>
</tr>
<tr>
<td>
<div id="msg_error">
<p id="pMensajeError">
<c:if test="${param.login_error eq 1}">
<fmt:message key="error.001" />
</c:if>
</p>
</div>
</td>
</tr>
</table>
</form>
<%@include file="/jsp/common/defaultBottom.jsp"%>
--%>
\ No newline at end of file
...@@ -6,6 +6,12 @@ import com.mx.dla.admin.dtos.UsuarioDTO; ...@@ -6,6 +6,12 @@ import com.mx.dla.admin.dtos.UsuarioDTO;
public interface UsuarioDAO { public interface UsuarioDAO {
public UsuarioDTO obtenerUsuario( @Param("expediente") String expediente ); public UsuarioDTO obtenerUsuario(@Param("expediente") String expediente);
public void actualizaEstadoSesion(@Param("estado") Integer estado, @Param("expediente") String expediente);
public void insertaBitacora(@Param("descripcion") String descripcion,
@Param("usuarioIntento") String usuarioIntento, @Param("deraccionIp") String deraccionIp,
@Param("userAgent") String userAgent);
} }
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<result property="materno" column="MATERNO" /> <result property="materno" column="MATERNO" />
<result property="email" column="EMAIL" /> <result property="email" column="EMAIL" />
<result property="idArea" column="ID_AREA" /> <result property="idArea" column="ID_AREA" />
<!-- Relación de 1 a 1 --> <!-- Relación de 1 a 1 -->
<association property="perfil" javaType="PerfilDTO"> <association property="perfil" javaType="PerfilDTO">
<id property="idPerfil" column="ID_PERFIL" /> <id property="idPerfil" column="ID_PERFIL" />
...@@ -22,24 +22,36 @@ ...@@ -22,24 +22,36 @@
</resultMap> </resultMap>
<select id="obtenerUsuario" resultMap="usuario" parameterType="map"> <select id="obtenerUsuario" resultMap="usuario"
parameterType="map">
select select
usr.EXPEDIENTE, usr.EXPEDIENTE,
usr.NOMBRE, usr.NOMBRE,
usr.PATERNO, usr.PATERNO,
usr.MATERNO, usr.MATERNO,
usr.EMAIL, usr.EMAIL,
usr.ID_AREA, usr.ID_AREA,
per.ID_PERFIL, per.ID_PERFIL,
per.DESC_PERFIL per.DESC_PERFIL
from from
DLA_C_USUARIO usr, DLA_C_USUARIO usr,
DLA_C_USUARIO_PERFIL usrper, DLA_C_USUARIO_PERFIL usrper,
DLA_C_PERFIL per DLA_C_PERFIL per
where where
usr.EXPEDIENTE = usrper.EXPEDIENTE usr.EXPEDIENTE = usrper.EXPEDIENTE
AND usrper.ID_PERFIL = per.ID_PERFIL AND usrper.ID_PERFIL = per.ID_PERFIL
AND usr.EXPEDIENTE = #{expediente} AND usr.EXPEDIENTE = #{expediente}
</select> </select>
<update id="actualizaEstadoSesion">
UPDATE DLA_C_USUARIO SET B_USUARIO_LOGUEADO =
#{estado} WHERE EXPEDIENTE = #{expediente}
</update>
<insert id="insertaBitacora">
INSERT INTO DLA_BITA_ACCESO
(ID, DESCRIPCION, USUARIO_INTENTO, DIRECCION_IP, USER_AGENT)
VALUES(DLA_BITA_ACCESO_SEQ.nextval, #{descripcion}, #{usuarioIntento}, #{deraccionIp}, #{userAgent})
</insert>
</mapper> </mapper>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment