Git Product home page Git Product logo

security's Issues

JokoSecurity escribe una excepcion cuando un token expira

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.

Evaluación de la causa

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.

Versiones afectadas

Todas, desde la actual (0.1.8) hacía atrás.

Como usuario deseo tener la applicación de ejemplo funcionando con base de datos H2

Los objetivos del presente issue:

  1. Crear un tag con el relese actual
  2. La aplicación ejemplo funciona con la última versión estable de Spring Boot Web Starter (a la fecha 1.5.9)
  3. Se corrige el #6
  4. Las instrucciones de ejemplo y la configuración default (application.properties) utiliza la base de datos H2 con generación automática mediante JPA de las tablas
  5. Existe un Postgresql.README que explica cómo configurar en ese tipo de motor de BD

Se debe crear un fork desde la rama develop y una vez concluído el aporte, solicitar el pull request.

Migrar a Spring Boot 2.x

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.

Persistir datos del mapa custom en base de datos

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.

Cambiar el tipo de datos de las PK a bigserial

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 .

Mejorar documentación de la configuración

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:

  • Documentar que se puede usar el secret en la BD
  • Documentar que la primera vez se genera la clave

Persistir información de los request originados por cada token/sesión

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

  1. Nro. de IP que genera el request
  2. Nro. de IP de la cabecera X-Forwarded-For (si existe)
  3. User Agent

Solucionar los javadoc warnings

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

Implementar un generador de semilla OTP con QRCode

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.

La clase Application.java tiene configuración no necesaria para librerías empaquetadas como JAR

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

No se esta generando un secreto en el caso que no haya uno todavia en la BD

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)

La tabla seed debe ir como evolución para el liquibase

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.

El nombre del schema es parametrizable en tiempo de compilacion

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:

  • Incluir un preprocesador para cambiar el schema de acuerdo al maven profile.
  • Tener la capacidad de regenerar el liquibase para que se use el nombre dinámico.

Como developer me gustaría un changelog

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 tabla audit parece no tener utilidad. Evaluar deprecarla

La tabla audit parece no tener utilidad alguna. Para emitir la opinión me paso en lo siguiente:

  1. Audit solo se llena desde un Controller en particular (AuditSessionController)
    Es decir, el cliente tiene que explícitamente llamar a este URL para ser auditado. Sin comprender el caso de uso que motivó a su creación, parece no tener sentido.

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.

  1. La información que se almacena en audit ya está en la tabla tokens.
    La información que se está pretendiendo guardar desde "audit" ya se encuentra en la tabla "tokens"

Propuesta

Mi propuesta concreta es eliminar la tabla Audit y los objetos que se construyen encima de ella.

Como administrador tengo servicios rest para un módulo de auditoría

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

Consultar por un criterio. Ejemplos

/api/secure/tokens/history/revisions/{userId}
/api/secure/tokens/history/revisions/{remoteIp}

Descargar reportes en formato JSON o CSV

/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]

Reactivar el test TokenControllerIntegrationTest#requestingTokenInfoShouldReturnOk

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

Stacktrace del test en error

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)

Evaluación

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

Agregar Continuous Integration (CI)

Agregar una tarea de Travis o CircleCI que ejecute los unit tests como requisito para el merge del proyecto.

  • Se debe eliminar el proyecto de ejemplo; actualizar el Readme y hacer referencia al 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

El index.html no corresponde al proyecto

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.