# **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)

### **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)