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 @@
Usuario y/o contraseña no vlidos.
</label>
</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">
<input id="loginEmail" type="text" name="j_username"
placeholder='Usuario' class="form-control">
......
......@@ -3,7 +3,10 @@ package com.mx.dla.admin.actions;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.ibatis.executor.result.ResultMapException;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.Authentication;
......@@ -42,10 +45,21 @@ public class InicioAction extends BaseContratoAction {
String retorno = SUCCESS;
try {
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());
ActionContext.getContext().getSession().remove("pmn");
ActionContext.getContext().getSession().remove("pmnReturn");
getSession().put("ipAdress",ipAddress);
getSession().put("userAgent",userAgent);
if (!this.getPmn().equals("0"))
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"?>
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/" security='none' />
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/css/**" access="permitAll" />
<intercept-url pattern="/design/**" access="permitAll" />
<intercept-url pattern="/images/**" access="permitAll" />
<intercept-url pattern="/js/**" access="permitAll" />
<http pattern="/" security='none' />
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/css/**" access="permitAll" />
<intercept-url pattern="/design/**" access="permitAll" />
<intercept-url pattern="/images/**" 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 -->
<intercept-url pattern="/jsp/**" access="isAuthenticated()" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<!-- <intercept-url pattern="/**" access="permitAll" /> -->
<authentication-manager alias="authenticationManager">
<authentication-provider>
<jdbc-user-service data-source-ref="dsDLA"
users-by-username-query="
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"
always-use-default-target="true" authentication-failure-url="/index.jsp?login_error=1" />
</http>
<authentication-manager alias="authenticationManager">
<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
<!-- Beans de los manejadores personalizados -->
<beans:bean id="customAuthenticationSuccessHandler" class="com.mx.dla.configuration.CustomAuthenticationSuccessHandler" />
<beans:bean id="customAuthenticationFailureHandler" class="com.mx.dla.configuration.CustomAuthenticationFailureHandler" />
<beans:bean id="customLogoutSuccessHandler" class="com.mx.dla.configuration.CustomLogoutSuccessHandler" />
</beans:beans>
......@@ -56,7 +56,7 @@
<!-- Session -->
<session-config>
<session-timeout>30</session-timeout>
<session-timeout>3</session-timeout>
</session-config>
<jsp-config>
......
......@@ -22,17 +22,8 @@
<link rel="stylesheet" href="${contextPath}/design/css/general.css">
<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>
<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 class="l-main-container">
<!--Main Content-->
......@@ -51,6 +42,11 @@
Usuario y/o contrase&ntilde;a no vlidos.
</label>
</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 class="form-group">
<input id="loginEmail" type="text" name="j_username"
......@@ -79,20 +75,6 @@
<script src="${contextPath}/design/js/shared/jquery.asonWidget.js"></script>
<script src="${contextPath}/design/js/plugins/plugins.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-->
<script src="${contextPath}/design/js/plugins/forms/validation/jquery.validate.min.js"></script>
......@@ -107,73 +89,4 @@
</script>
</body>
</html>
<%--
<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
</html>
\ No newline at end of file
......@@ -6,6 +6,12 @@ import com.mx.dla.admin.dtos.UsuarioDTO;
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 @@
<result property="materno" column="MATERNO" />
<result property="email" column="EMAIL" />
<result property="idArea" column="ID_AREA" />
<!-- Relación de 1 a 1 -->
<association property="perfil" javaType="PerfilDTO">
<id property="idPerfil" column="ID_PERFIL" />
......@@ -22,24 +22,36 @@
</resultMap>
<select id="obtenerUsuario" resultMap="usuario" parameterType="map">
<select id="obtenerUsuario" resultMap="usuario"
parameterType="map">
select
usr.EXPEDIENTE,
usr.NOMBRE,
usr.PATERNO,
usr.MATERNO,
usr.EMAIL,
usr.ID_AREA,
per.ID_PERFIL,
per.DESC_PERFIL
usr.EXPEDIENTE,
usr.NOMBRE,
usr.PATERNO,
usr.MATERNO,
usr.EMAIL,
usr.ID_AREA,
per.ID_PERFIL,
per.DESC_PERFIL
from
DLA_C_USUARIO usr,
DLA_C_USUARIO_PERFIL usrper,
DLA_C_PERFIL per
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 = #{expediente}
usr.EXPEDIENTE = usrper.EXPEDIENTE
AND usrper.ID_PERFIL = per.ID_PERFIL
AND usr.EXPEDIENTE = #{expediente}
</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>
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