Desarrollar servicios en Java, incluidas las API REST, no siempre fue fácil ni productivo hasta que llegó la primavera y cambió el panorama. Han pasado muchos años desde entonces, y han surgido nuevos marcos en la comunidad.
Uno de estos marcos fue Micronaut. Está desarrollado por OCI, la misma empresa detrás de Grails, y su objetivo es ayudar a los desarrolladores a crear microservicios y aplicaciones sin servidor.
También está Quarkus, otro framework que ganó popularidad en el último año. Desarrollado por RedHat, Quarkus promete ofrecer un inicio rápido y un menor uso de memoria, dos problemas comunes al desarrollar servicios REST en Java.
Con todas estas opciones, hay una pregunta muy importante que hacer: ¿qué tan fácil es crear un servicio con cada uno de estos tres marcos?
En este tutorial, crearás una aplicación REST segura utilizando Spring, Micronaut y Quarkus para ver en qué se diferencian entre sí y cuál se adapta mejor a tus necesidades.
Tabla de contenidos
- Requisitos previos para su API REST de Java
- Crear una Cuenta Okta para la Administración de Usuarios
- Generar tokens Utilizando el depurador OpenID Connect
- Crear una API REST de Java con Micronaut
- Desarrollar su Servicio Java
- Reflexiones finales sobre las API REST Con Java: Micronaut, Quarkus y Spring Boot
Spring Boot
Si lo desea, puede ver este tutorial como un screencast. Prerequisites
- Requisitos previos para su API REST de Java
- Crear un Octa Cuenta para la Administración de usuarios
- Generar tokens Mediante el depurador OpenID Connect
- Cree una API REST de Java con Micronaut
- Desarrolle su servicio Java
- Cree una API REST de Java con Quarkus
- Cree una API REST de Java con Spring Boot
- Reflexiones finales sobre las API REST Con Java: Micronaut, Quarkus y Spring Boot
Requisitos previos para su API REST de Java
Este tutorial utiliza Maven 3+. Asegúrese de que esté instalado y disponible para su uso antes de continuar. Ciertamente también puedes usar Gradle, pero YMMV.
Vas a crear aplicaciones que autentiquen solicitudes usando OAuth 2.0, protegidas por una aplicación Okta. ¿No tienes una cuenta Okta? No te preocupes, se tarda menos de un minuto en crear uno nuevo. No solo eso, Okta soporta estándares como JWT, OAuth 2.0 y OIDC. Proporcionamos soporte para frameworks conocidos como Java EE, Spring Boot y Spring Security. Diablos, incluso tenemos un plugin Maven que automatiza todo para ti.
no Hay necesidad de reinventar la rueda!
Crear un Octa Cuenta para la Administración de usuarios
Abra el terminal y ejecutar el siguiente comando:
mvn com.okta:okta-maven-plugin:register
se le pedirá que ingrese la siguiente información:
- Primer Nombre
- apellido
- Correo electrónico
- Empresa
una Vez que haya respondido a las preguntas, usted recibirá un correo electrónico para activar su nueva cuenta. Después de activar su cuenta, ejecute el siguiente comando:
mvn com.okta:okta-maven-plugin:spring-boot
Este comando crea una aplicación para usted con flujo de código de autenticación y URI de redirección de Spring Security para Okta.
Para recordarla mejor, puede crear la misma aplicación manualmente:
- Vaya a la página de inicio de desarrolladores de Okta e inicie sesión en su cuenta.
- haga Clic en Aplicaciones > Agregar a la Aplicación > Web > Siguiente.
Usted verá la siguiente pantalla:
Antes de continuar, realice los cambios siguientes en la aplicación:
- Uri de redireccionamiento de inicio de Sesión:
http://localhost:8080/login/oauth2/code/okta
https://oidcdebugger.com/debug
- tipo de Subvención permitido
- Codigo
- Implícito (Híbrido)
El implícita tipo de subvención (con la identidad y el Token de Acceso permitido comprobar) es necesaria para recuperar un token de acceso en su navegador.
Los campos no mencionados anteriormente pueden mantener sus valores predeterminados.
Después de terminarlo, haga clic en Listo. ¡Tu aplicación está lista!
El siguiente paso es aprender a generar un token válido usándolo.
Generar tokens Mediante el depurador OpenID Connect
Okta le permite administrar a sus usuarios en la nube mediante sus API. También le permite proteger sus aplicaciones utilizando OAuth 2.0 y OpenID Connect (también conocido como OIDC). OAuth 2.0 proporciona un mecanismo para la autorización delegada, lo que significa que no tiene que almacenar credenciales de usuario en su aplicación. En su lugar, puede delegar eso a un proveedor OAuth 2.0 (Okta, en este caso). OIDC proporciona una capa de identidad encima de OAuth 2.0 y es por eso que las empresas como Okta se llaman «proveedores de identidad», o IDPs.
Ha registrado su aplicación con Okta y ahora puede generar un token para obtener acceso a ella. Uno de los URI de redirección de inicio de sesión que registró es para el sitio web OpenID Connect.
Sus solicitudes se validarán mediante un token. Para generar este token, utilizará el depurador OpenID Connect. Este sitio web le proporcionará una manera fácil de generar credenciales para los usuarios de su aplicación Okta.
Ir a la etiqueta https://oidcdebugger.com y complete la siguiente información:
- Autorizar URI:
https://{yourOktaDomain}/oauth2/default/v1/authorize
- URI de Redirección:
https://oidcdebugger.com/debug
- ID de cliente:
{yourOktaClientId}
- Alcance:
openid email profile
- Estado:
dev
- Nonce: (mantenga el valor predeterminado)
- Tipo de respuesta:
token
Puede encontrar el valor de {yourOktaDomain}
en la esquina superior derecha de la página de inicio de su cuenta:
Para encontrar su ID de cliente Okta, siga los pasos a continuación:
- Vaya a Aplicaciones
- Seleccione Mi aplicación web
- Haga clic en General
El ID de cliente estará disponible en la sección Credenciales de cliente:
Después de completar todos los campos, haga clic en Enviar solicitud. Serás redirigido a tu página de inicio de sesión de Okta.
Una vez que se haya autenticado correctamente, se le redirigirá al depurador OIDC de nuevo, donde podrá ver el token generado:
Usará este token para acceder de forma segura a los servicios que va a crear.
Ahora que tiene una cuenta Okta y sabe cómo generar tokens utilizando su aplicación Okta, ¡comencemos a comparar los marcos!
Cree una API REST de Java con Micronaut
El primer paso para desarrollar su servicio Micronaut es descargar SDKMAN.. ¡SDKMAN! es una herramienta para gestionar versiones paralelas de varios SDK, que utilizarás para instalar el cliente Micronaut.
¡Puedes descargar SDKMAN! ejecutando el siguiente comando:
curl -s https://get.sdkman.io | bash
Ahora, usted puede instalar Micronaut sí mismo. Simplemente ejecute el siguiente comando en el terminal:
sdk install micronaut
Después de que el comando termine de ejecutarse, tendrá la última versión de Micronaut disponible en su computadora.
¡Ya está listo para comenzar a desarrollar la aplicación!
Desarrolle su servicio Java
Vaya al directorio en el que desea crear su aplicación y ejecute el siguiente comando:
mn create-app com.okta.rest.app --build maven
con Este comando creará un proyecto con la estructura básica de un Micronaut proyecto. Micronaut usa Gradle de forma predeterminada, pero como estás usando --build maven
, usará Maven en su lugar.
El siguiente paso es agregar las bibliotecas de seguridad dentro del proyecto. Editar la etiqueta pom.xml
archivo y agregar las siguientes dependencias:
<dependency> <groupId>io.micronaut</groupId> <artifactId>micronaut-security</artifactId></dependency><dependency> <groupId>io.micronaut</groupId> <artifactId>micronaut-security-jwt</artifactId></dependency>
Estas dependencias se habilita la seguridad – específicamente OAuth 2.0 con JWT – dentro de su proyecto. Ahora que tiene todas las dependencias en su lugar, puede comenzar a crear su punto final.
Crear la siguiente clase en el src/main/java/com/okta/rest/controller
:
package com.okta.rest.controller;import io.micronaut.http.MediaType;import io.micronaut.http.annotation.Controller;import io.micronaut.http.annotation.Get;import io.micronaut.http.annotation.Produces;import io.micronaut.security.annotation.Secured;import io.micronaut.security.rules.SecurityRule;import java.security.Principal;@Controller("/hello")public class HelloController { @Get @Secured(SecurityRule.IS_AUTHENTICATED) @Produces(MediaType.TEXT_PLAIN) public String hello(Principal principal) { return "Hello, " + principal.getName() + "!"; }}
El @Controller
anotación indica a Micronaut que este componente se recibirán las solicitudes en el /hello
ruta de acceso.
La clase tiene un solo método, llamado hello()
. La anotación @Get
muestra que el método recibirá solicitudes HTTP GET. Necesita @Produces
porque el tipo de retorno predeterminado de Micronaut es un objeto JSON. Dado que está devolviendo texto simple, debe definir explícitamente esta información en el método.
La última anotación es @Secured
. Simplemente le dice a Micronaut que este método solo es accesible para usuarios autenticados.
Ahora tiene un controlador seguro, pero aún no ha definido la configuración de seguridad. Configuremos Micronaut para que se conecte a su aplicación Okta.
cambiar el nombre de src/main/resources/application.yml
a application.properties
y agregue la siguiente configuración de seguridad:
micronaut.security.enabled=truemicronaut.security.token.jwt.enabled=truemicronaut.security.token.jwt.signatures.jwks.okta.url=https://{yourOktaDomain}/oauth2/default/v1/keys
Reemplace {yourOktaDomain}
con el valor de su Octa cuenta.
La configuración anterior habilita la seguridad mediante OAuth 2.0. Usted declara que su cliente OAuth 2.0 proviene de Okta, especificando el emisor de su organización Okta.
También está habilitando el uso de tokens web JSON o JWT. Dado que desea leer la información de Okta, debe declarar dónde puede encontrar sus JWKS (Conjunto de claves Web JSON) para validar las firmas JWT.
¡Es hora de probar su servicio! Iniciar la aplicación ejecutando el siguiente comando:
./mvnw mn:run
Con su aplicación, ejecute el siguiente comando:
curl -X GET -I http://localhost:8080/hello
El comando anterior producirá un resultado similar a este:
HTTP/1.1 401 UnauthorizedDate: Tue, 8 Jan 2019 15:47:36 GMTtransfer-encoding: chunkedconnection: close
Como puede ver, la solicitud de no ir a través de. Para que funcione, debe pasar el token de acceso OAuth 2.0 recuperado por el depurador OIDC. Asigne el token de acceso a una variable TOKEN
en su shell.
TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...
Ejecutar el siguiente comando:
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello
Ahora funciona como se esperaba! Esta vez recibe el mensaje de saludo como respuesta:
Hello, [email protected]!
Puede ver que Micronaut requiere muy poco código para crear una API REST segura. Si contara las líneas de código, descubriría que ~24% son dependencias en XML (8 líneas), el código Java es solo 22 líneas de código y la configuración de seguridad toma 3 líneas. La compatibilidad con OAuth 2.0 integrada de Micronaut facilita la integración con Okta e incluso tienen una Guía para Okta en su documentación.
Genial! Ahora veamos cómo creas la misma aplicación usando Quarkus.
Cree una API REST de Java con Quarkus
Para desarrollar su aplicación utilizando Quarkus, solo necesita tener instalado Maven, no se requieren otras dependencias.
¡Comencemos a crear tu aplicación! Vaya al directorio que desea crear y ejecutar el siguiente comando:
mvn io.quarkus:quarkus-maven-plugin:1.8.1.Final:create \ -DprojectGroupId=com.okta.rest \ -DprojectArtifactId=quarkus \ -DclassName="com.okta.rest.quarkus.HelloResource" \ -Dpath="/hello" \ -Dextensions="jwt"
El comando anterior crea un proyecto con la Quarkus plugin de Maven. Creará un recurso llamado HelloResource
, que recibirá solicitudes en la ruta /hello
. También está agregando la extensión JWT de Quarkus en el proyecto.
Una vez creado el proyecto, edite src/java/com/okta/rest/quarkus/HelloResource.java
y agregue información de usuario al método hello()
:
package com.okta.rest.quarkus;import io.quarkus.security.Authenticated;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.Produces;import javax.ws.rs.core.Context;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.SecurityContext;import java.security.Principal;@Path("/hello")public class HelloResource { @GET @Path("/") @Authenticated @Produces(MediaType.TEXT_PLAIN) public String hello(@Context SecurityContext context) { Principal userPrincipal = context.getUserPrincipal(); return "Hello, " + userPrincipal.getName() + "!"; }}
La clase anterior se comportan de la misma manera como la creada en el Micronaut. Lee la información del usuario en función del token que se generó en la solicitud y devuelve un mensaje de saludo al usuario que se encuentra.
Todavía no ha configurado Quarkus con su emisor y claves de Okta, así que hagámoslo.
Editar src/main/resources/application.properties
y agregue el código siguiente:
mp.jwt.verify.publickey.location=https://{yourOktaDomain}/oauth2/default/v1/keysmp.jwt.verify.issuer=https://{yourOktaDomain}/oauth2/default
Hecho! La versión Quarkus de su aplicación está lista para ser probada. Ir a la carpeta del proyecto y ejecutar el siguiente comando:
./mvnw compile quarkus:dev
El comando anterior se inicie su aplicación.
El primer paso es asegurarse de que recibe un 401 - Unauthorized
cuando no utiliza las credenciales correctas.
Ejecute el siguiente comando en la terminal:
curl -X GET -I http://localhost:8080/hello
Como era de esperar, el resultado es un HTTP 401 respuesta:
HTTP/1.1 401 Unauthorizedwww-authenticate: Bearer {token}Content-Length: 0
Si ejecuta esta misma solicitud, incluido el token del depurador OIDC, debería devolver el mensaje de bienvenida.
Ejecute el siguiente comando:
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello
Él trabajó como un encanto! En mi caso, el resultado fue:
Hello, [email protected]!
Quarkus requiere aún menos líneas de código de Micronaut! Genera una aplicación con dependencias incluidas, tiene 25 líneas de código Java y solo 2 líneas de configuración. Sí, lines of code es una comparación tonta, pero también muestra cómo estos marcos requieren muy poco código para desarrollar aplicaciones seguras.
Dos abajo, falta uno! Ahora que ha podido implementar la aplicación en Micronaut y Quarkus, terminemos creando la misma aplicación con Spring Boot.
Cree una API REST de Java con Spring Boot
Spring Boot no tiene requisitos previos para comenzar a crear su aplicación, ¡así que comencemos por crear el proyecto!
Abra su terminal y ejecute el siguiente comando:
curl https://start.spring.io/starter.zip -d language=java \ -d bootVersion=2.3.4.RELEASE \ -d dependencies=web,okta \ -d packageName=com.okta.rest \ -d name=spring-boot \ -d type=maven-project \ -o spring-boot.zip
El comando anterior creará un spring-boot.zip
archivo con un Resorte de Arranque de la aplicación que utiliza Maven. Puede extraer el archivo en un directorio spring-boot
utilizando el siguiente comando.
unzip spring-boot.zip -d spring-boot
Ahora vamos a implementar el controlador que se reciben las solicitudes.
Crear un paquete com.okta.rest.controller
y una clase HelloController
en él:
package com.okta.rest.controller;import org.springframework.security.core.annotation.AuthenticationPrincipal;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import java.security.Principal;@RestControllerpublic class HelloController { @GetMapping("/hello") public String hello(@AuthenticationPrincipal Principal principal) { return "Hello, " + principal.getName() + "!"; }}
La configuración es muy similar a la de otros marcos. Anota la clase con @RestController
para que Spring sepa que recibirá solicitudes en la clase. @GetMapping
recibirá solicitudes HTTP GET en la ruta /hello
. Para recuperar el usuario autenticado, utilice la anotación @AuthenticationPrincipal
.
A diferencia de los otros frameworks, no es necesario especificar que este extremo esté autenticado, ya que Spring ya controla esta información desde sus configuraciones.
El último paso es agregar la información del emisor, para que el soporte OIDC de Spring Security pueda descubrir automáticamente los puntos finales con los que necesita comunicarse.
Editar src/main/resources/applications.properties
y agregue la siguiente configuración:
okta.oauth2.issuer=https://{yourOktaDomain}/oauth2/default
Vamos a probarlo! Inicia tu aplicación Spring Boot con Maven.
./mvnw spring-boot:run
a Continuación, abra un terminal y ejecutar el siguiente comando:
curl -X GET -I http://localhost:8080/hello
La respuesta es un error HTTP 401, ya que no incluyen el token:
HTTP/1.1 401Set-Cookie: JSESSIONID=316DCFD55C302A8D69EFD865411DFA77; Path=/; HttpOnlyWWW-Authenticate: BearerX-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=blockCache-Control: no-cache, no-store, max-age=0, must-revalidatePragma: no-cacheExpires: 0X-Frame-Options: DENYContent-Length: 0Date: Thu, 09 Jan 2020 15:46:34 GMT
Prueba de nuevo, ahora se pasa el token:
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello
funcionó! Al igual que con los otros servicios, el resultado de este comando es el siguiente:
Hello, [email protected]!
Los relojes de arranque de resorte en la menor cantidad de código requerido: ¡17 líneas de Java y solo 1 línea de configuración! La primavera siempre ha sido excelente para facilitar la vida de los desarrolladores, por lo que esto no es una sorpresa.
Eso es todo! ¡Implementó una API REST Java básica en los tres frameworks!
Reflexiones finales sobre las API REST Con Java: Micronaut, Quarkus y Spring Boot
Cuando se trata de desarrollar su API REST, los tres frameworks hicieron bien el trabajo. Con solo un poco de código y cierta configuración, pudo desarrollar una aplicación segura utilizando Okta y OAuth 2.0.
La primavera ha existido durante muchos años, es muy popular y tiene muchas características alrededor de su ecosistema. Personalmente, sigo creyendo que es la mejor opción disponible al programar en Java.
Micronaut y Quarkus están creciendo en popularidad y ganando impulso dentro de la comunidad Java. Si se enfrenta a problemas de rendimiento, o tal vez si tiene ganas de cambiar, puede probar uno de ellos y ver cómo va.
El rendimiento es el punto de comparación más destacado entre estos tres marcos. Si está buscando un inicio rápido en un entorno sin servidor o la capacidad de crear imágenes nativas con GraalVM, es probable que Micronaut y Quarkus funcionen bien para usted. Solo por diversión, los tiempos de inicio de cada una de estas aplicaciones son los siguientes (basados en el promedio de tres intentos):
- Micronaut: 474ms
- Quarkus: 1132ms
- Spring Boot: 1014ms
Obtuve estos números al ejecutar los objetivos Maven de desarrollo de cada marco.
- Micronaut:
./mvnw mn:run
- Quarkus:
./mvnw compile quarkus:dev
- Inicio de la Primavera:
./mvnw spring-boot:run
Estos comandos no están optimizados para la velocidad, por lo que empaqueté cada aplicación con ./mvnw package
y los inicié con java -jar
.
- Micronaut: 596ms
- Quarkus: 658ms
- Spring Boot: 1878ms
NOTA: Estos números se calcularon en un MacBook Pro 2019 con una CPU Intel Core i9 de 8 núcleos a 2,4 GHz y 64 GB de RAM. Se utilizó OpenJDK 15 sin configuración JAVA_OPTS
.
Si buscas tiempos de inicio aún más rápidos, puedes usar GraalVM. En lugar de realizar pruebas de cronometraje yo mismo, miré la documentación de cada proyecto.
- Micronaut: 12 ms según la creación de su primera aplicación de Micronaut Graal.
- Quarkus: 14 ms según Quarkus y GraalVM: Hibernación de arranque a Velocidad Supersónica, Tamaño Subatómico en InfoQ. Los documentos de Quarkus no indican la hora de inicio.
- Bota de resorte: 44 ms según Spring Graal Native 0.6.0 lanzado.
Al final, podrá desarrollar de forma productiva una aplicación segura, independientemente de la elección que haga.
Quiero echar un vistazo al código fuente? Puedes encontrarlo en GitHub en okta-java-rest-api-comparison-example.
¿Desea obtener más información sobre Java, las API REST y las aplicaciones seguras? Aquí hay algunas otras publicaciones de nuestro blog que pueden resultarle útiles:
- Vea GraalVM Convertir su Java en Binarios
- Guía de Java de OAuth 2.0: Asegure su aplicación en 5 Minutos
- Microservicios Java con Spring Boot y Spring Cloud
- Cómo desarrollar una aplicación Quarkus con Autenticación Java y OIDC
- Autenticación Simple con Spring Security
Para más publicaciones como esta, siga a @oktadev en Twitter. También publicamos regularmente screencasts en nuestro canal de YouTube.
Registro de cambios:
- 23 de septiembre de 2020: Actualizado a Micronaut 2.0.2, Quarkus 1.8.1 y Spring Boot 2.3.4. Vea los cambios de código en la aplicación de ejemplo en GitHub. Los cambios a esta publicación se pueden ver en oktadeveloper/okta-blog#423.
- 21 de mayo de 2020: Se agregaron tiempos de inicio para
java -jar
y se ejecuta con GraalVM. Los cambios a este artículo se pueden ver en oktadeveloper/okta-blog#304. - 20 de mayo de 2020: Actualizado a Micronaut 1.3.5, Quarkus 1.4.2 y Spring Boot 2.3.0. Vea los cambios de código en la aplicación de ejemplo en GitHub. Los cambios a este artículo se pueden ver en oktadeveloper/okta-blog#301.
- 30 de enero de 2020: Actualizado para optimizar Micronaut en función de los comentarios del equipo de Micronaut. También se vuelven a calcular los tiempos de inicio en función de un promedio de tres intentos. Vea los cambios de código en la aplicación de ejemplo en GitHub. Los cambios a este artículo se pueden ver en oktadeveloper/okta-blog#176.