jokoframework / security Goto Github PK
View Code? Open in Web Editor NEWJoko Security provee la capacidad de realizar autenticacion y autorizacion por medio de Tokens JWT
License: Apache License 2.0
Joko Security provee la capacidad de realizar autenticacion y autorizacion por medio de Tokens JWT
License: Apache License 2.0
Actualmente Joko Security recibe un JSON para la autenticación del formato:
{
"username":"sodep",
"password":"PONER_AQUI_EL_PASSWORD",
"custom": {
"codigoEmpresa":123,
"codigoSucursal": 2,
"codigoCaja":982341
}
}
pero el mapa custom
no es persistido en la base de datos.
El objetivo del ticket es que esta información sea almacenada en una columna y pueda ser recuperado en una instancia cualquiera de un token.
To this date there's still no fix for: https://nvd.nist.gov/vuln/detail/CVE-2022-1471
There are still no fix for
https://mvnrepository.com/artifact/org.yaml/snakeyaml/1.33
Currently it's being intentionally ignored in dependency-check exclusions
Se debe agregar al proyecto, servicios que permitan generar una semilla aleatoria con su respectivo QRCode que permita tener códigos para utilizar la aplicación FreeOTP mobile como un factor de autenticación.
Se debe utilizar el proyecto, https://freeotp.github.io/ y asociar el código a una sesión autenticada mediante Joko Security y JWT.
Los objetivos del presente issue:
application.properties
) utiliza la base de datos H2 con generación automática mediante JPA de las tablasSe debe crear un fork desde la rama develop
y una vez concluído el aporte, solicitar el pull request.
Cuando un token expira Joko security escribe una excepción como la siguiente:
2017-11-29 10:02:43.044 DEBUG 23946 --- [nio-8080-exec-2] i.g.j.s.springex.JokoSecurityFilter : /api/clients/1542561/feeds/2017/11 from User-Agent: okhttp/3.3.1 Unable to authenticate class io.jsonwebtoken.ExpiredJwtException: JWT expired at 2017-11-28T22:17:26-0300. Current time: 2017-11-29T10:02:43-0300
2017-11-29 10:02:43.044 DEBUG 23946 --- [nio-8080-exec-1] i.g.j.s.springex.JokoSecurityFilter : /api/clients/1542561/budget/2017/11 from User-Agent: okhttp/3.3.1 Unable to authenticate class io.jsonwebtoken.ExpiredJwtException: JWT expired at 2017-11-28T22:17:26-0300. Current time: 2017-11-29T10:02:43-0300
2017-11-29 10:02:43.045 TRACE 23946 --- [nio-8080-exec-2] i.g.j.s.springex.JokoSecurityFilter : Token received: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxMDE1NTM2NDY3OTQyMTcxNSIsImV4cCI6MTUxMTkxODI0NiwiaWF0IjoxNTExOTA3NDQ2LCJqdGkiOiJVSkFDRUg3Sk1VSFk1N0JIU1FNUSIsImpva28iOnsidHlwZSI6IkFDQ0VTUyIsInJvbGVzIjpbIkVORF9VU0VSIl0sInByb2ZpbGUiOiJERUZBVUxUIn19.DrT4lsQfJXxVavm5joIDvp29DLeMmrYWiRzRuhjWEmr78_JKMxj1arrxDHgxVLxChTu4oeYBxDFPdd6HB_GoJw
2017-11-29 10:02:43.045 TRACE 23946 --- [nio-8080-exec-1] i.g.j.s.springex.JokoSecurityFilter : Token received: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxMDE1NTM2NDY3OTQyMTcxNSIsImV4cCI6MTUxMTkxODI0NiwiaWF0IjoxNTExOTA3NDQ2LCJqdGkiOiJVSkFDRUg3Sk1VSFk1N0JIU1FNUSIsImpva28iOnsidHlwZSI6IkFDQ0VTUyIsInJvbGVzIjpbIkVORF9VU0VSIl0sInByb2ZpbGUiOiJERUZBVUxUIn19.DrT4lsQfJXxVavm5joIDvp29DLeMmrYWiRzRuhjWEmr78_JKMxj1arrxDHgxVLxChTu4oeYBxDFPdd6HB_GoJw
2017-11-29 10:02:43.046 ERROR 23946 --- [nio-8080-exec-2] i.g.j.s.springex.JokoSecurityFilter : Error validando el token.
io.jsonwebtoken.ExpiredJwtException: JWT expired at 2017-11-28T22:17:26-0300. Current time: 2017-11-29T10:02:43-0300
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:365)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:458)
at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:518)
at io.github.jokoframework.security.util.SecurityUtils.parseToken(SecurityUtils.java:227)
at io.github.jokoframework.security.services.impl.TokenServiceImpl.parse(TokenServiceImpl.java:322)
at io.github.jokoframework.security.services.impl.TokenServiceImpl$$FastClassBySpringCGLIB$$b683a18c.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at io.github.jokoframework.security.services.impl.TokenServiceImpl$$EnhancerBySpringCGLIB$$8e6ca5e7.parse(<generated>)
at io.github.jokoframework.security.springex.JokoSecurityFilter.validateToken(JokoSecurityFilter.java:97)
at io.github.jokoframework.security.springex.JokoSecurityFilter.doFilter(JokoSecurityFilter.java:55)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Esto resulta muy inconveniente, puesto que no es un error y el log se va llenando de estas excepciones.
Examinando el código de Joko-security nos encontramos que en la clase JokoSecurityFilter (linea 72) se encuentra esta porción de código:
} catch (IllegalArgumentException | JwtException var7) {
String uri = httpRequest.getRequestURI();
String userAgent = httpRequest.getHeader("User-Agent");
LOGGER.debug(uri + " from User-Agent: " + userAgent + " Unable to authenticate " + var7.getClass() + ": " + var7.getMessage());
LOGGER.trace("Token received: " + token);
LOGGER.error("Error validando el token.", var7);
return null;
}
Como se puede ver la lina que imprime la excepción (var7) es la causante del problema. En mi opinión esto no debería de escribirse con un nivel tan alto de LOG (error actualmente) puesto que realmente no es un comportamiento erróneo del sistema, sino algo que naturalmente puede pasar. Esta excepción podría escribirse como máximo en TRACE.
Todas, desde la actual (0.1.8) hacía atrás.
Agregar una tarea de Travis o CircleCI que ejecute los unit tests como requisito para el merge del proyecto.
joko_backend_starter_kit
como el proyecto de referencia/ejemplo.Los unit tests deberían correr con la base de datos H2 así como lo hace ahora el proyecto de Backend
Cuando está puesta la propiedad para que el secreto se guarde en la BD (Tabla keychain) se deberia de generar automaticamente el secreto de no existir (Según el archivo RUN.md), pero esto no esta ocurriendo, simplemente revienta porque no logro obtener el keychain cuando se inicializa el proyecto.
(Como Workaround se puede insertar a mano en la BD un Keychain con id=1 y un string al azar como secreto)
El proyecto al compilar con maven posee varios JavaDoc warnings. El objetivo de este ticket es limpiarlos:
[WARNING] Javadoc Warnings
[WARNING] /Users/danicricco/sources/joko/security/src/main/java/io/github/jokoframework/security/util/SecurityUtils.java:246: warning: no description for @param
[WARNING] * @param filePath
[WARNING] ^
[WARNING] /Users/danicricco/sources/joko/security/src/main/java/io/github/jokoframework/security/util/TXUUIDGenerator.java:188: warning: no description for @param
[WARNING] * @param l
[WARNING] ^
[WARNING] /Users/danicricco/sources/joko/security/src/main/java/io/github/jokoframework/security/util/TXUUIDGenerator.java:189: warning: no description for @param
[WARNING] * @param size
[WARNING] ^
[WARNING] /Users/danicricco/sources/joko/security/src/main/java/io/github/jokoframework/security/util/TXUUIDGenerator.java:190: warning: no description for @return
[WARNING] * @return
Para poder migrar de una versión anterior, se debe colocar el cambio que agrega la tabla seed
como evolución para el liquibase.
<changeSet author="danicricco" id="1518643732286-101">
<createTable tableName="seed"
schemaName="joko_security"
remarks="Guarda las semillas OTP">
<column name="id" type="BIGSERIAL">
<constraints nullable="false"/>
</column>
<column name="user_id" type="VARCHAR(255)"/>
<column name="seed_secret" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="danicricco" id="1518643732286-102">
<addPrimaryKey columnNames="id" constraintName="seed_pkey"
tableName="seed" schemaName="joko_security"/>
</changeSet>
Se debe pasar ese changeset del inicial
al evolución
.
Necesitamos generar los entities y que el nombre del schema pueda ser parametrizable en tiempo de compilación. La idea es poder utilizar ciertas base de dato que no soportan el concepto de schema.
Para solucionar el ticket se debería de tener dos elementos:
Un ingreso/login exitoso, genera un refresh_token
que luego se utiliza para ralizar los demás requests REST.
El objetivo de este ticket, es almacenar en un esquema tipo master/detail
todos los requests generados por ese refresh_token
, con informaciones de auditoría obtenidas del request
X-Forwarded-For
(si existe)Existe una inconsistencia entre el nombre del atributo y el nombre de la columna para liquibase.
Ref:
https://github.com/jokoframework/security/blob/master/src/main/java/io/github/jokoframework/security/entities/SecurityProfile.java#L92
Objetivo: Consultar el nombre del atributo o la columna consultando el histórico del mismo y la necesidad real de la columna dentro del proyecto.
Spring 1.x y las librerías de las que depende está dejando de tener soporte, como eso tiene sus implicancias de seguridad, e objetivo de este ticket es migrar a las librería de Spring Boot 2.x y Java 11.
Aparecio una vulnerabilidad relacionada a Gradle que impide construir el proyecto
Información sobre el CVE-2019-15052:
https://nvd.nist.gov/vuln/detail/CVE-2019-15052
En el archivo de changelog de liquibase; se debe cambiar los tipos de datos de las PK a bigserial, y eliminar la creación de secuencias que existen actualmente.
Verificar que los test unitarios sigan corriendo en una base de datos recién creada.
Aumentar el nro. de release en el pom.xml
.
El archivo que encuentra en src/main/resources/public/index.html no corresponde al proyecto. Esto resulta muy inconveniente puesto que al ser incluido en un proyecto que no posee "index", es la página que se termina mostrando.
El objetivo de este ticket es implementar el método getSessions para que retorne las sesiones por usuario y fecha. Este método ya existe pero no está implementado aún, o retorna una lista vacía siempre.
La tabla audit parece no tener utilidad alguna. Para emitir la opinión me paso en lo siguiente:
Si se desea auditar la emisión de tokens, esto no debe ser voluntario. Un cliente podría llamar, obtener un token y decidir no llamar al método de auditoría. La auditoría debería de darse como consecuencia de que se emitió un token.
Mi propuesta concreta es eliminar la tabla Audit y los objetos que se construyen encima de ella.
Yo estoy usando la versión 0.1.4.1 pero veo que la última versión es la 0.1.8. Sin embargo, no logro identificar cuales son los cambios entre las distintas versiones.
Me encantaría que exista un changelog, donde se pueda ver claramente la evolución del producto. Idealmente un release notes, donde podamos ver cual es la compatibilidad hacia atras del módulo
La idea es mejorar la documentación de la configuración. Por ejemplo hay dos opciones que son posibles y no están correctamente documentadas:
Se debe actualizar las dependencias del pom.xml
y aumentar el número de release para security
.
El test TokenControllerIntegrationTest#requestingTokenInfoShouldReturnOk fue desactivado porque tiene un problema de compatibilidad de librerías. Como todos los demás test funcionan y el problema tiene que ver con una librería que se usa en test, se decidió momentaneamente desactivar la funcionalidad.
La librería se usa solo a nivel de test y se comprobó el correcto funcionamiento del sistema en general.
El objetivo de este ticket es resolver el problema de compatibilidad de librerías y volver a activar el test
java.lang.NoClassDefFoundError: com/jayway/jsonpath/Predicate
at org.springframework.test.util.JsonPathExpectationsHelper.<init>(JsonPathExpectationsHelper.java:61)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.<init>(JsonPathResultMatchers.java:61)
at org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath(MockMvcResultMatchers.java:192)
at io.github.jokoframework.security.controller.TokenControllerIntegrationTest.requestingTokenInfoShouldReturnOk(TokenControllerIntegrationTest.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
Parece que la librería en cuestión es:
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>0.8.1</version>
<scope>test</scope>
</dependency>
Se probó rápidamente cambiar a la última versión 2.4.0 y no se tuvo éxito
El proyecto utiliza JPA para el manejo de persistencia, con el proveedor Hibernate.
Se desea contar con servicios rest que me permitan tener auditoría con Envers y consultar los cambios realizados a la tabla representada por TokenEntity
/api/secure/tokens/history/revisions/{userId}
/api/secure/tokens/history/revisions/{remoteIp}
/api/secure/tokens/report?format=json
Parámetros comunes a ambos formatos
startDate
: Fecha de inicio, formato ISO 8601 :2018-02-28T23:19:06+00:00
endDate
: Fecha de fin, formato [ISO 8601]
En concreto, la documentación de Spring Boot menciona algunos requisitos que debe tener el Application.java
para que un proyecto Spring Boot sea deployable como war.
Joko security no necesita cumplir esos requisitos, como por ejemplo extender de SpringBootServletInitializer
.
Se debería modificar y quitar estas configuraciones, teniendo en cuenta que el objetivo de este proyecto es poder ser utilizado como librería empaquetada como JAR en otros proyectos.
Problemas similares pueden encontrarse aquí: spring-projects/spring-boot#5033
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.