# **Configuracion Servidor Oauth2** ## Powered by **Ory Hydra** En esta guía vamos a configurar un servidor de _Autenticación_ para el protocolo **Oauth2**, se hará uso tanto de imágenes como de snipets de código para aclarar el correcto funcionamiento y configuración del servidor. Concretamente, la implementación del servidor que vamos a configurar la ofrece [**Ory Hydra**](https://www.ory.sh/). Antes de empezar a configurar el servidor hay que tener claros ciertos conceptos relacionados con el protocolo **Oauth2** en sí. Recomiendo encarecidamente leer la especificación propia del [framework](https://tools.ietf.org/html/rfc6749) así como la propia documentación de la implementación de [**Ory Hydra**](https://www.ory.sh/docs/guides/master/). ## **Conceptos Básicos** ### Roles :::info 1. _Cliente_ ~ Aplicación que necesita permisos. Accederá a los recursos. Necesitará los toquens. 2. _Servidor de recursos_ ~ API que sirve a los clientes con los recursos deseados. 3. _Servidor de autenticación_ ~ Servidor que hace de enlace entre el cliente y el servidor de recursos. Autentifica, expide tokens, comprueba validez de tokens, etc. 4. _Propietario_ ~ El usuario físico que es dueño de los recursos. Es el que garantiza los permisos al cliente en última instancia. 5. _Recurso_ ~ Cualquier dato, permiso, etc. que se le provee a un cliente. Deben estar protegidos ya que es la información sensible. ::: ### **Tipos de autenticaciones** 1. _Auth_Code_ 2. _Implicit_ 3. _Resource_Owner_Password_credentials_ 4. _Extension_ 5. [_ClientCredentials_](#client--credentials) (El que vamos a utilizar) ![](https://i.imgur.com/lf2rAuC.png) ### **Obteniendo autorizaciones/tokens** En este apartado vamos a tener en cuenta que sólo nos interesa la autenticación mediante el flujo [_Client_Credentials_](https://tools.ietf.org/html/rfc6749#section-4.4). Para este flujo queda a juicio del desarrollador cómo validar previamente al _cliente_, ten en cuenta que esto es obligatorio en pos de la seguridad. Esta autenticación puede realizarse mediante un flujo básico, basado en usuario/contraseña, o mediante cualquier otro método. Para tener una idea visual de cómo sería el flujo, por favor, comprueba el diagrama de este [flujo](#client--credentials). **1. Realizando peticion** ```json { grant_type: "client_credentials" (obligatorio) scope: "a,b,c,all" (opcional) } ``` **2. Obteniendo respuesta** ~ A parte del formato más abajo, el servidor debe añadir a la cabecera: ```json { cache-control: "no-store" pragma: "no-cache" } ``` ```json <!-- Si la respuesta es correta, código 200 --> { access_token: "qwe.asd.zxc" (obligatorio) token_type: "bearer" (obligatorio) expires_in: 3600 (opcional) scope: "all" (opcional) } <!-- Si la respuesta es errónea, código 400+ --> { invalid_request: "invalid_client" (obligatorio) invalid_grant: "unathorized_client" (obligatorio) unsuported_grant_type: "invalid_scope" (opcional) error_description: "mimimi" (opcional) error_url: "https:localhost/error" (opcional) } ``` ## **Configuración del Servidor** Una vez comprendidos ciertos términos y elementos sobre el protocolo comenzamos con la configuración del servidor. Existen ejemplos detallados de cómo instalar y probar el servidor que provee **Ory Hydra** en su propia documentación. En caso de que algo no quedase claro o pareciera incompleto comprobar su [documentación](https://www.ory.sh/docs/guides/master/hydra/4-install/#lets-check-if-its-running-ok) puede ser un paso muy esclarecedor. **Ory Hydra** es una implementación escrita en [_GO_](https://golang.org/). Su configuración es relativamente sencilla ya que TODA la configuración hace uso de variables del entorno, las cuales recorreremos y explicaré. :::warning **INFO** ~ Toda la documentación de las variables de entorno que vamos a ver a continuación es posible consultarla, yo sólo comentaré las más importantes y básicas, mediante el comando (desde la terminal). ```bash hydra help all <!-- O tambien --> hydra help serve all ``` ::: :::danger **IMPORTANTE** ~ **Ory Hydra** es un Software vivo actualmente, por lo tanto van lanzando nuevas versiones, de hecho, conla última [versión](https://github.com/ory/hydra/releases) (8.0.0) separaron el servidor público(acceso para las aplicaciones _cliente_) del de administración (acceso para administración de _cliente_, _token_, etc.). Recomiendo encarecidamente comprobar su [documentación](https://www.ory.sh/docs/) on-line. ::: ### **Configuración del Core** :::info - DATABASE_URL ~ Url donde se aloja nuestra BBDD. - SYSTEM_SECRET ~ Secreto que usará **Ory hydra** para generar las semillas a la hora de encriptar datos. Podemos proveerle de uno, en caso contrario **Ory Hydra** crea uno nuevo aleatorio el cual, por cierto, no te da por pantalla. - COOKIE_SECRET ~ Mismo fucionamiento que el del sistema pero para las cokies del navegador. Si está vacío usará por defecto el mismo que el del sistema. - PORT ~ Puertos donde escuchará el servidor. Por defecto `:4444` para el acceso público y `:4445` para el acceso de administración. - HOST ~ Interfaces por donde escuchará el servidor. Por defecto, vacío, escuchará en todas. ::: ### **Configuración controles Oauth2** :::info - OAUTH2_ISSUER_URL ~ Url pública de nuestra instalación del servidor. - OAUTH2_LOGIN_URL ~ Url donde se redireccionará al _cliente_ para comenzar el flujo de autenticación. - OAUTH2_CONSENT_URL ~ Url donde se redireccionará al _cliente_ para que el _propietario_ garantice acceso a los recursos. - OAUTH2_ERROR_URL ~ Url a la que se redireccionará en caso de errores en las respuestas. ::: ### **Configuración HTTPS** :::info - HTTPS_ALLOW_TERMINATION_FROM ~ Provoca que el servidor se sirva de `http` en vez de `https` para las comunicaciones. No es seguro, es preferible utilizarlo sólo en desarrollo o testeo. - HTTPS_TLS_CERT_PATH ~ Dirección donde se encuentra el certificado _TLS_ (codificación pem) - HTTPS_TLS_KEY_PATH ~ Dirección donde se encuentra la clave privada del certificado (codificación pem) - HTTPS_TLS_CERT ~ String representando el certificado _TLS_ (codificación pem). Se puede utilizar en vez de `HTTPS_TLS_CERT_PATH`. - HTTPS_TLS_KEY ~ String representando la clave privada del certificado _TLS_ (codificación pem). Se puede utilizar en vez de `HTTPS_TLS_KEY_PATH`. ::: ### **Configuración/creación de un Cliente** :::info - -c (Obligatorio) ~ Lista de URLs válidas donde recibir las respuestas del _cliente_. - -g ~ Lista de autorizaciones válidas para este usuario. Deberán coincidir con los _tokens_ que se expidan para este usuario. - -r ~ Lista de los tipos de respuesta que podrá recibir, por defecto es "code". - -a ~ Lista del "scope" a los que el _propietario_ dió acceso a este _cliente_. - -id ~ Id del _cliente_. - -secret ~ Secreto del _cliente_. No es seguro crearlos por la terminal dado a que pueden quedar registrados en los logs del sistema, o de cualquier software intermedio utilizado (ej. _cmder.exe_). Este secreto DEBE conocerlo únicamente nuestro servidor y el _cliente_ en cuestión. DEBE ser guardado por el _cliente_ ya que no le será posible comprobarlo más adelante. - -name ~ Nombre del _cliente_. No confundir con el id, este sólo sirve como información adicional. - -endpoint ~ URL donde el servidor está hosteado. Por defecto se toma el valor de la variable de entorno `HYDRA_ADMIN_URL`. - --skip-tls-verify ~ Opción para que el servidor acepte certificados _TLS_ autofirmados. NO usar nunca en producción, sólo válido para testeo y desarrollo. ::: ## Configurando Nuestro Servidor Tan sólo necesitamos hacer uso de unas pocas variables ya que estamos utilizando los puertos que **Ory Hydra** configura por defecto (`:4444` para el público y `:4445` para el privado) :::warning **INFO** ~ Toda la configuración se puede modificar con los comandos listados más arriba. Para cualquier duda simplmente utiliza el comando "help" desde la terminal tal y como se comentó en una de las secciones previas. ::: :::danger **Importante** ~ Doy por sentado que la BBDD de datos YA EXISTE, en caso contrario al intentar lanzar el servidor recibirás errores diversos y poco motivadores. Además, también asumo que los puertos que va a utilizar el servidor está/n libre/s, es tú trabajo comprobar que sea así, si no estás seguro compruébalo con el siguiente comando... ``` bash <!--WINDOWS/LINUX--> netstat -ano ``` ::: **1. Configuramos la URL BBDD** ``` bash <!--WINDOWS--> set DATABASE_URL=mysql://[USUARIO]:[CONTRASEÑA]@tcp(LOCALHOST)/[NOMBRE_BBDD]?parseTime=true <!--LINUX--> export DATABASE_URL=mysql://[USUARIO]:[CONTRASEÑA]@tcp'(LOCALHOST)'/[NOMBRE_BBDD]?parseTime=true ``` **2. Configuramos el secreto de nuestro sistema** ``` bash <!--WINDOWS--> set SYSTEM_SECRET=$y$t3m_4_t3$t1ng_v3ry_$3cr3t <!--LINUX--> export SYSTEM_SECRET=$y$t3m_4_t3$t1ng_v3ry_$3cr3t ``` **3. Configuramos el expedidor de tokens** ``` bash <!--WINDOWS--> set OAUTH2_ISSUER_URL=https://localhost:9000/ <!--LINUX--> export OAUTH2_ISSUER_URL=https://localhost:9000/ ``` **4. Configuramos la url del login** ``` bash <!--WINDOWS--> set OAUTH2_LOGIN_URL=http://localhost:9020/login <!--LINUX--> export OAUTH2_LOGIN_URL=https://localhost:9020/login ``` **5. Configuramos la url donde se realizan los consentimientos (scopes de los tokens)** ``` bash <!--WINDOWS--> set OAUTH2_CONSENT_URL=http://localhost:9020/consent <!--LINUX--> export OAUTH2_CONSENT_URL=https://localhost:9020/consent ``` **6. Migramos la BBDD para crear las tablas necesarias** ```bash <!--WINDOWS--> hydra migrate sql %DATABASE_URL% <!--LINUX--> hydra migrate sql $DATABASE_URL ``` **7. Creamos un _Cliente_** ```javascript <!--WINDOWS/LINUX--> hydra clients create \ -c http://127.0.0.1:9010/callback \ -g client_credentials \ -r token,code,id_token \ -a a,b,c,all \ --id pablete \ --secret secretaso \ --name pablito \ --endpoint https://oauth2.metacontratas.com:444 \ --token-endpoint-auth-method client_secret_post \ --skip-tls-verify (solo para TESTEO y DESARROLLO) ``` :::info __INFO__ Deberías asegurarte, a la hora de definir el "endpoint" del usuario, de la url/ip donde la parte de _administracion de_ __ORY HYDRA__ está siendo hosteada. En nuestro caso es la dirección `https://oauth2.metacontratas.com:444` pero podrían cambiar tanto la _ip_ como el _puerto_. ::: **8. Iniciamos el servidor** ```javascript <!--WINDOWS/LINUX--> <!--SI QUEREMOS LANZAR EL SERVIDOR COMPLETO--> hydra serve all --dangerous-force-http <!--SI SOLO QUEREMOS ARRANCAR LA PARTE PUBLICA--> hydra serve public --dangerous-force-http <!--SI SOLO QUEREMOS ARRANCAR LA PARTE DE ADMINISTRACION--> hydra serve admin --dangerous-force-http ``` ## **Referencias** ### Tecnologías utilizadas - [Ory Hydra](https://www.ory.sh/) - [Go](https://golang.org/) - [Docker](https://www.docker.com/) (En caso de seguir los tutoriales de **ORY HYDRA**. En esta guía se ha instalado previamente __ORY HYDRA__ en el path del sistema) - [Oauth2 Framework](https://oauth.net/2/) ### Recursos a consultar - [Ory Hydra docs](https://www.ory.sh/docs/) - [Ory Hydra Versions](https://github.com/ory/hydra/releases) - [Ory Hydra Oauth2 Server API](https://www.ory.sh/docs/api/hydra/) - [Oauth2 Framework](https://tools.ietf.org/html/rfc6749) - [Discord ORY HYDRA](https://discordapp.com/channels/417987379878428673/417987380302315521)