diff --git a/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java b/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java
index d61a328f4353b10ee58bec766bb2ba24b047cd82..6239c85caa1aeca7f4fa838df9a940e11d0907a0 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java
@@ -53,7 +53,7 @@ public class UserAPI {
    */
   public User registerUser(RegisterRequest registerRequest) {
     String url = USER_API_URL;
-    System.out.println(registerRequest + " " + registerRequest.getPassword());
+    System.out.println(url + " " + registerRequest);
     ResponseEntity<User> userResponse = restTemplate.postForEntity(url, registerRequest, User.class);
     if (!userResponse.getStatusCode().is2xxSuccessful()) {
       String errorMessage = "Failed to register user: " + userResponse.getStatusCode() + ". " + userResponse.getBody();
@@ -80,4 +80,10 @@ public class UserAPI {
     restTemplate.put(url, body, id);
   }
 
+  public void deleteUser(User user) {
+    String url = USER_API_URL + "/{id}";
+
+    restTemplate.delete(url, user.getId());
+  }
+
 }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateConfig.java b/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateConfig.java
index 9ab4fa43b1587585cfdf4c1cd6d80b9556a78606..dbcefe7ec34f65cca38b60db09be7355a98b73a7 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateConfig.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateConfig.java
@@ -7,19 +7,16 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.client.RestTemplate;
 
-import com.uva.authentication.interceptor.AuthHttpInterceptor;
-
 @Configuration
 public class RestTemplateConfig {
 
     @Autowired
-    private AuthHttpInterceptor jwtInterceptor;
+    private RestTemplateInterceptor interceptor;
 
     @Bean
     RestTemplate restTemplate() {
         RestTemplate restTemplate = new RestTemplate();
-        restTemplate.setInterceptors(List.of(jwtInterceptor));
-
+        restTemplate.setInterceptors(List.of(interceptor));
         return restTemplate;
 
     }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateInterceptor.java b/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..25b59946b262e6e8026f5f05ebd098e7dc9674be
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateInterceptor.java
@@ -0,0 +1,33 @@
+package com.uva.authentication.config;
+
+import org.springframework.http.HttpRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.stereotype.Component;
+
+import com.uva.authentication.utils.JwtUtil;
+
+import java.io.IOException;
+
+@Component
+public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
+
+  @Autowired
+  private JwtUtil jwtUtil;
+
+  @Override
+  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
+      throws IOException {
+
+    // Añadir el encabezado "Authorization" con el valor "Bearer <token>"
+    HttpHeaders headers = request.getHeaders();
+    headers.add("Authorization",
+        "Bearer " + jwtUtil.getOwnInternalToken());
+
+    // Continuar con la solicitud
+    return execution.execute(request, body);
+  }
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java b/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java
index 83041cc56f5019ea047e41c56dae8224828f792a..7dfa56acc48bad46f862f259c15f90b8e172ad01 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java
@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
 @RestController
+@RequestMapping("auth")
 @CrossOrigin(origins = "*")
 public class AuthController {
 
@@ -23,55 +24,52 @@ public class AuthController {
     @PostMapping("/login")
     public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
         try {
-            String token = authService.login(loginRequest);
-            return ResponseEntity.ok(new JwtAuthResponse(token));
+            return authService.login(loginRequest);
         } catch (HttpClientErrorException e) {
             if (e.getStatusCode() == HttpStatus.FORBIDDEN) {
-                return new ResponseEntity<String>(e.getMessage(), HttpStatus.FORBIDDEN);
+                return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN);
             }
         }
-        return new ResponseEntity<String>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
+        return new ResponseEntity<>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
     }
 
     @PostMapping("/register")
     public ResponseEntity<?> register(@RequestBody RegisterRequest registerRequest) {
         try {
-            String token = authService.register(registerRequest);
-            return ResponseEntity.ok(new JwtAuthResponse(token));
+            return authService.register(registerRequest);
         } catch (HttpClientErrorException e) {
-            if (e.getStatusCode() == HttpStatus.CONFLICT) {
-                return new ResponseEntity<String>(e.getMessage(), HttpStatus.CONFLICT);
-            }
-            e.printStackTrace(System.err);
+            if (e.getStatusCode() == HttpStatus.CONFLICT)
+                return new ResponseEntity<>(e.getMessage(), HttpStatus.CONFLICT);
         }
 
-        return new ResponseEntity<String>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
+        return new ResponseEntity<>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
     }
 
-    private boolean validStrings(String... args) {
-        for (String arg : args) {
-            if (arg == null || arg.isBlank())
-                return false;
-        }
-        return true;
+    @PostMapping("/password")
+    public ResponseEntity<?> changePassword(@RequestBody Map<String, String> json,
+            @RequestHeader(value = "Authorization", required = false) String authorization) {
+        if (authorization == null || !authorization.startsWith("Bearer "))
+            return new ResponseEntity<>(HttpStatus.FORBIDDEN);
+
+        String token = authorization.substring(7);
+
+        String actualPassword = json.get("password");
+        String newPassword = json.get("newPassword");
+
+        return authService.changePassword(token, actualPassword, newPassword);
     }
 
-    @PostMapping("/password")
-    public ResponseEntity<?> postMethodName(@RequestBody Map<String, String> json) {
-        // TODO adaptar a comportamiento de admin
-        String email = json.get("email");
-        String actualPassword = json.get("actual");
-        String newPassword = json.get("new");
+    @PostMapping("/delete/{id}")
+    public Object postMethodName(@PathVariable int id, @RequestBody Map<String, String> json,
+            @RequestHeader(value = "Authorization", required = false) String authorization) {
+        if (authorization == null || !authorization.startsWith("Bearer "))
+            return new ResponseEntity<>(HttpStatus.FORBIDDEN);
 
-        if (!validStrings(email, actualPassword, newPassword))
-            return new ResponseEntity<Void>(HttpStatus.BAD_REQUEST);
+        String token = authorization.substring(7);
 
-        try {
-            // TODO extraer información del token?
-            String token = authService.changePassword(email, actualPassword, newPassword);
-            return ResponseEntity.ok(new JwtAuthResponse(token));
-        } catch (Exception e) {
-            return new ResponseEntity<Void>(HttpStatus.BAD_REQUEST);
-        }
+        String actualPassword = json.get("password");
+
+        return authService.deleteUser(token, id, actualPassword);
     }
+
 }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/controllers/TokenController.java b/java/services/auth/src/main/java/com/uva/authentication/controllers/TokenController.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e33376dd18629f48bd6863bd8beb06465455901
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/controllers/TokenController.java
@@ -0,0 +1,47 @@
+package com.uva.authentication.controllers;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.uva.authentication.models.JwtAuth;
+import com.uva.authentication.services.TokenService;
+
+@RestController
+@RequestMapping("/token")
+public class TokenController {
+
+  @Autowired
+  private TokenService tokenService;
+
+  @PostMapping("/validate")
+  public ResponseEntity<?> validateToken(@RequestBody JwtAuth tokenRequest) {
+    boolean isValid = tokenService.validateToken(tokenRequest.getToken());
+    if (isValid) {
+      return ResponseEntity.ok("Token is valid");
+    } else {
+      return new ResponseEntity<>("Token not valid or expired", HttpStatus.UNAUTHORIZED);
+    }
+  }
+
+  @PostMapping("/info")
+  public ResponseEntity<?> getTokenInfo(@RequestBody JwtAuth tokenRequest) {
+    return tokenService.getTokenInf(tokenRequest.getToken());
+  }
+
+  @PostMapping("/service")
+  public ResponseEntity<?> identifyService(@RequestBody JsonNode request) {
+    JsonNode name = request.get("service");
+
+    if (name == null)
+      return new ResponseEntity<>("Missing required fields", HttpStatus.BAD_REQUEST);
+
+    return tokenService.identifyService(name.asText());
+  }
+
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/exceptions/GlobalExceptionHandler.java b/java/services/auth/src/main/java/com/uva/authentication/exceptions/GlobalExceptionHandler.java
deleted file mode 100644
index 6d4b8d58dbb5560de50b5b2149cbe3f181687446..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/exceptions/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.uva.authentication.exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-@ControllerAdvice
-public class GlobalExceptionHandler {
-
-    @ExceptionHandler(HotelNotFoundException.class)
-    public ResponseEntity<Map<String, Object>> handleHotelNotFound(HotelNotFoundException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
-    }
-
-    @ExceptionHandler(InvalidRequestException.class)
-    public ResponseEntity<Map<String, Object>> handleInvalidRequest(InvalidRequestException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
-    }
-
-    @ExceptionHandler(InvalidDateRangeException.class)
-    public ResponseEntity<Map<String, Object>> handleInvalidDateRange(InvalidDateRangeException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
-    }
-
-    // @ExceptionHandler(Exception.class)
-    // public ResponseEntity<Map<String, Object>> handleGeneralException(Exception
-    // ex) {
-    // Map<String, Object> body = new HashMap<>();
-    // body.put("timestamp", LocalDateTime.now());
-    // body.put("message", "An unexpected error occurred: " + ex.getMessage());
-
-    // return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
-    // }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/exceptions/HotelNotFoundException.java b/java/services/auth/src/main/java/com/uva/authentication/exceptions/HotelNotFoundException.java
deleted file mode 100644
index c642139b421a5cf864218fa2d0063f955335c5b7..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/exceptions/HotelNotFoundException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.authentication.exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(HttpStatus.NOT_FOUND) // Devuelve un 404 cuando se lanza la excepción
-public class HotelNotFoundException extends RuntimeException {
-    public HotelNotFoundException(int id) {
-        super("Hotel not found with id: " + id);
-    }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidDateRangeException.java b/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidDateRangeException.java
deleted file mode 100644
index c3dc917fb03495480007365b117e185521cf7bf2..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidDateRangeException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.uva.authentication.exceptions;
-
-public class InvalidDateRangeException extends RuntimeException {
-    public InvalidDateRangeException(String message) {
-        super(message);
-    }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidRequestException.java b/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidRequestException.java
deleted file mode 100644
index 499a320e58ecd7576cbfff39101db14395f0edbe..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidRequestException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.authentication.exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(HttpStatus.BAD_REQUEST)
-public class InvalidRequestException extends RuntimeException {
-    public InvalidRequestException(String message) {
-        super(message);
-    }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/interceptor/AuthHttpInterceptor.java b/java/services/auth/src/main/java/com/uva/authentication/interceptor/AuthHttpInterceptor.java
deleted file mode 100644
index b64a0f69a673dcac07e93616c3affad5f6be3be5..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/interceptor/AuthHttpInterceptor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.uva.authentication.interceptor;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpRequest;
-import org.springframework.http.client.ClientHttpRequestExecution;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.http.client.ClientHttpRequestInterceptor;
-import org.springframework.stereotype.Component;
-
-import com.uva.authentication.models.remote.User;
-import com.uva.authentication.models.remote.UserRol;
-import com.uva.authentication.utils.JwtUtil;
-
-import java.io.IOException;
-
-@Component
-public class AuthHttpInterceptor implements ClientHttpRequestInterceptor {
-
-  @Autowired
-  private JwtUtil jwtUtil;
-
-  private String token;
-  private final User USER = new User(-1, "auth", "auth@dev.com", null, UserRol.ADMIN);
-
-  private String getAccessToken() {
-    if (token == null || token.isEmpty()) {
-      // TODO cambiar también si el token ha caducado
-      token = jwtUtil.generateToken(USER);
-    }
-    return token;
-
-  }
-
-  @Override
-  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
-      throws IOException {
-    // Generar o cargar el JWT token desde el bean JwtUtil
-    String jwtToken = getAccessToken();
-
-    // System.out.println("Using token " + jwtToken);
-
-    // Agregar el token al encabezado Authorization
-    request.getHeaders().add("Authorization", "Bearer " + jwtToken);
-
-    // Continuar con la ejecución de la solicitud
-    return execution.execute(request, body);
-  }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/AuthResponse.java b/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuth.java
similarity index 51%
rename from java/services/auth/src/main/java/com/uva/authentication/models/AuthResponse.java
rename to java/services/auth/src/main/java/com/uva/authentication/models/JwtAuth.java
index 148730189d6c5a29df507bc3cd10eef7a9b274e6..1736439a1b93980155336707350f695a9f56c0ed 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/models/AuthResponse.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuth.java
@@ -1,20 +1,16 @@
 package com.uva.authentication.models;
 
-import com.uva.authentication.models.remote.UserRol;
-
 import lombok.AllArgsConstructor;
+import lombok.Data;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 
-@AllArgsConstructor
-@NoArgsConstructor
-@Setter
 @Getter
-public class AuthResponse {
-  private int id;
-  private String name;
-  private String email;
-  private String password;
-  private UserRol rol;
+@Setter
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class JwtAuth {
+  private String token;
 }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuthResponse.java b/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuthResponse.java
deleted file mode 100644
index a9566954c35ce71864881e320843e270a998b9da..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuthResponse.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.uva.authentication.models;
-
-public class JwtAuthResponse {
-  private String token;
-
-  public JwtAuthResponse(String token) {
-    this.token = token;
-  }
-
-  // Getter
-  public String getToken() {
-    return token;
-  }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/TokenData.java b/java/services/auth/src/main/java/com/uva/authentication/models/TokenData.java
new file mode 100644
index 0000000000000000000000000000000000000000..d503f9193f58a44dee2a0b184ee654af4893999f
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/TokenData.java
@@ -0,0 +1,55 @@
+package com.uva.authentication.models;
+
+import java.lang.reflect.Field;
+
+import com.auth0.jwt.interfaces.Claim;
+import com.auth0.jwt.interfaces.DecodedJWT;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Data
+public class TokenData {
+  private Integer id;
+  private String name;
+  private String email;
+  private String rol;
+  private String service;
+
+  private String subject;
+  private String audience;
+  private Long ttl;
+
+  public TokenData(DecodedJWT decoded, long ttl) {
+
+    subject = decoded.getSubject();
+    audience = decoded.getAudience().get(0);
+    this.ttl = ttl;
+
+    for (Field field : this.getClass().getDeclaredFields()) {
+      field.setAccessible(true);
+
+      // Verificamos si el campo está en el mapa y asignamos el valor
+      Claim claim = decoded.getClaim(field.getName());
+      if (!claim.isMissing()) {
+        try {
+          // Dependiendo del tipo de campo, asignamos el valor
+          if (field.getType() == Integer.class) {
+            field.set(this, Integer.parseInt(claim.asString()));
+          } else if (field.getType() == String.class) {
+            field.set(this, claim.asString());
+          }
+        } catch (IllegalAccessException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+  }
+
+  public boolean isAdmin() {
+    return rol != null && rol == "ADMIN";
+  }
+}
\ No newline at end of file
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/TokenRequest.java b/java/services/auth/src/main/java/com/uva/authentication/models/TokenRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e63522e1a8660e71573fdb018aaae5f5596517ce
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/TokenRequest.java
@@ -0,0 +1,16 @@
+package com.uva.authentication.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TokenRequest {
+  private String token;
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java b/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java
index ae8de366340950b1bb5af476600408446a2d3f32..10049fc82e340fab5885cbd523f0962fc03292f5 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java
@@ -16,6 +16,7 @@ public class User extends RegisterRequest {
 
   public User(int id, String email, String password, String name, UserRol rol) {
     super();
+    this.id = id;
     setEmail(email);
     setName(name);
     setPassword(password);
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserRol.java b/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserRol.java
index 2cb39bb4f6174faf20c7174269c835f7c6b80cc2..fe4d90dd1dd595f4c09ec699b452910352b406d5 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserRol.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserRol.java
@@ -1,5 +1,5 @@
 package com.uva.authentication.models.remote;
 
 public enum UserRol {
-  ADMIN, AUTH, HOTEL_ADMIN, CLIENT
+  ADMIN, HOTEL_ADMIN, CLIENT
 }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java b/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java
index 67cf0b7308c3979274697da16bc0f0f103227aa9..03f2b6c132f4bf9531f891d34471d6484197a9dd 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java
@@ -3,12 +3,16 @@ package com.uva.authentication.services;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.servlet.function.EntityResponse;
 
 import com.uva.authentication.api.UserAPI;
+import com.uva.authentication.models.JwtAuth;
 import com.uva.authentication.models.LoginRequest;
 import com.uva.authentication.models.RegisterRequest;
+import com.uva.authentication.models.TokenData;
 import com.uva.authentication.models.remote.User;
 import com.uva.authentication.utils.JwtUtil;
 import com.uva.authentication.utils.SecurityUtils;
@@ -35,17 +39,17 @@ public class AuthService {
    * @return token for identify the user
    * @throws HttpClientErrorException(FORBIDDEN) if the credentials are invalid
    */
-  public String login(LoginRequest loginRequest) {
+  public ResponseEntity<?> login(LoginRequest loginRequest) {
     User user = userAPI.getUserByEmail(loginRequest.getEmail());
 
-    if (!authenticateUser(loginRequest, user)) {
+    if (!authenticateUser(loginRequest, user))
       throw new HttpClientErrorException(HttpStatus.FORBIDDEN, "Invalid credentials");
-    }
 
-    return jwtUtil.generateToken(user);
+    String token = jwtUtil.generateToken(user);
+    return ResponseEntity.ok(new JwtAuth(token));
   }
 
-  public String register(RegisterRequest registerRequest) {
+  public ResponseEntity<?> register(RegisterRequest registerRequest) {
     String plainTextPassword = registerRequest.getPassword();
     // Ciframos la contraseña
     String hashPass = SecurityUtils.encrypt(plainTextPassword);
@@ -56,21 +60,66 @@ public class AuthService {
     BeanUtils.copyProperties(user, logReq);
     // Recuperamos la contraseña y lo loggeamos
     logReq.setPassword(plainTextPassword);
-    System.err.println(logReq);
     return login(logReq);
   }
 
-  public String changePassword(String email, String actualPass, String newPass) {
+  private boolean validStrings(String... args) {
+    for (String arg : args) {
+      if (arg == null || arg.isBlank())
+        return false;
+    }
+    return true;
+  }
+
+  private User getUser(String email, String password) {
     User user = userAPI.getUserByEmail(email);
-    // Validamos la anterior contraseña
-    if (SecurityUtils.checkPassword(actualPass, user.getPassword())) {
+    boolean correctPassword = SecurityUtils.checkPassword(password, user.getPassword());
+    return correctPassword ? user : null;
+  }
+
+  public ResponseEntity<?> changePassword(String token, String actualPass, String newPass) {
+    TokenData decoded = jwtUtil.decodeToken(token);
+    if (decoded == null)
+      return new ResponseEntity<>(HttpStatus.FORBIDDEN);
+
+    String email = decoded.getEmail();
+    User user = getUser(email, actualPass);
+
+    boolean changePasswordAllowed = decoded.isAdmin() || user != null;
+
+    if (user != null && !validStrings(actualPass, newPass))
+      return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+
+    if (changePasswordAllowed) {
       // Actualizamos la nueva
       String hashPass = SecurityUtils.encrypt(newPass);
       userAPI.changePassword(user, hashPass);
       // Hacemos un login con los nuevos datos
       return login(new LoginRequest(email, newPass));
     } else {
-      throw new HttpClientErrorException(HttpStatus.FORBIDDEN, "Invalid credentials");
+      return new ResponseEntity<>("Invalid credentials", HttpStatus.FORBIDDEN);
+    }
+  }
+
+  public ResponseEntity<?> deleteUser(String token, int id, String password) {
+    TokenData decoded = jwtUtil.decodeToken(token);
+    if (decoded == null)
+      return new ResponseEntity<>(HttpStatus.FORBIDDEN);
+
+    String email = decoded.getEmail();
+    User user = getUser(email, password);
+
+    boolean changePasswordAllowed = decoded.isAdmin()
+        || (user != null && user.getId() == id);
+
+    if (user != null && !validStrings(password))
+      return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+
+    if (changePasswordAllowed) {
+      userAPI.deleteUser(user);
+      return new ResponseEntity<>(HttpStatus.ACCEPTED);
+    } else {
+      return new ResponseEntity<>("Invalid credentials", HttpStatus.FORBIDDEN);
     }
   }
 }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/services/TokenService.java b/java/services/auth/src/main/java/com/uva/authentication/services/TokenService.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2a00805f914c4aa95e29e244ece3826db25796c
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/services/TokenService.java
@@ -0,0 +1,35 @@
+package com.uva.authentication.services;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import com.uva.authentication.models.JwtAuth;
+import com.uva.authentication.models.TokenData;
+import com.uva.authentication.utils.JwtUtil;
+
+@Service
+public class TokenService {
+
+  @Autowired
+  private JwtUtil jwtUtil;
+
+  public boolean validateToken(String token) {
+    return jwtUtil.validate(token) != null;
+  }
+
+  public ResponseEntity<?> identifyService(String name) {
+    if (name == null)
+      return new ResponseEntity<>("Token has expire or is malformed", HttpStatus.FORBIDDEN);
+    String token = jwtUtil.generateInternalToken(name);
+    return ResponseEntity.ok(new JwtAuth(token));
+  }
+
+  public ResponseEntity<?> getTokenInf(String token) {
+    TokenData decoded = jwtUtil.decodeToken(token);
+    if (decoded == null)
+      return new ResponseEntity<>("Token has expire or is malformed", HttpStatus.FORBIDDEN);
+    return ResponseEntity.ok(decoded);
+  }
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java b/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java
index 7b5bbf50066d94d8de2fced81890d5ce8ea93569..d633043cce2da7d19a75b7bf32db38bd52905e5f 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java
@@ -1,44 +1,117 @@
 package com.uva.authentication.utils;
 
 import java.util.Date;
-
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpClientErrorException;
 
 import com.auth0.jwt.JWT;
 import com.auth0.jwt.algorithms.Algorithm;
+import com.uva.authentication.models.TokenData;
 import com.uva.authentication.models.remote.User;
 
+import com.auth0.jwt.interfaces.DecodedJWT;
+
+import java.time.Instant;
+
 @Component
 public class JwtUtil {
 
+  @Value("${security.jwt.kid}")
+  private String kid;
+
   @Value("${security.jwt.secret-key}")
   private String secretKey;
 
-  @Value("${security.jwt.kid}")
-  private String kid;
+  @Value("${security.jwt.internal.expiration}")
+  private long intJwtExpiration;
+
+  @Value("${security.jwt.external.expiration}")
+  private long extJwtExpiration;
+
+  private String token;
+
+  private static final String SERVICE = "AUTH_SERVICES";
 
-  @Value("${security.jwt.expiration-time}")
-  private long jwtExpiration;
+  public String getOwnInternalToken() {
+
+    // Si no hay token, no es valido o quedan 10 seg para caducar se genera otro
+    if (token == null || validate(token) == null ||
+        decodeToken(token).getTtl() <= 10) {
+      token = generateInternalToken(SERVICE);
+    }
+
+    return token;
 
-  public long getExpirationTime() {
-    return jwtExpiration;
+  }
+
+  public String generateInternalToken(String service) {
+    String email = service.toLowerCase() + "@internal.com";
+    Algorithm algorithm = Algorithm.HMAC256(secretKey);
+
+    return JWT
+        .create()
+
+        .withKeyId(kid)
+        .withIssuedAt(new Date())
+        .withExpiresAt(new Date(System.currentTimeMillis() + intJwtExpiration * 1000))
+
+        .withSubject(service)
+        .withAudience("INTERNAL")
+
+        // DATA
+        .withClaim("service", service)
+        .withClaim("email", email)
+
+        .sign(algorithm);
   }
 
   public String generateToken(User user) {
     Algorithm algorithm = Algorithm.HMAC256(secretKey);
+
     return JWT
         .create()
+
         .withKeyId(kid)
+        .withIssuedAt(new Date())
+        .withExpiresAt(new Date(System.currentTimeMillis() + extJwtExpiration * 1000))
+
+        .withSubject(SERVICE)
+        .withAudience("EXTERNAL")
+
+        // DATA
         .withClaim("id", user.getId())
         .withClaim("name", user.getName())
         .withClaim("email", user.getEmail())
         .withClaim("rol", user.getRol().toString())
-        .withIssuedAt(new Date())
-        .withExpiresAt(new Date(System.currentTimeMillis() + jwtExpiration * 1000))
+
         .sign(algorithm);
   }
 
-  // TODO estaría guapo recuperar métodos de validación para el token de petición
-  // para este servicio
+  public DecodedJWT validate(String token) {
+    try {
+      return JWT.require(Algorithm.HMAC256(secretKey)).build().verify(token);
+    } catch (Exception e) {
+      return null;
+    }
+  }
+
+  public TokenData decodeToken(String token) {
+    DecodedJWT decoded = validate(token);
+    if (decoded == null)
+      return null;
+    return new TokenData(decoded, calculateTTL(decoded));
+  }
+
+  private long calculateTTL(DecodedJWT decodedJWT) {
+    if (decodedJWT == null)
+      throw new HttpClientErrorException(HttpStatus.FORBIDDEN);
+
+    long exp = decodedJWT.getExpiresAt().toInstant().getEpochSecond();
+    long now = Instant.now().getEpochSecond();
+
+    return exp - now;
+  }
+
 }
diff --git a/java/services/auth/src/main/resources/application.properties b/java/services/auth/src/main/resources/application.properties
index c9d72501a6b64ab7f91a39562614adfa601ef98e..ad4a9a515522af4efcda2a87f59dc1902879136f 100644
--- a/java/services/auth/src/main/resources/application.properties
+++ b/java/services/auth/src/main/resources/application.properties
@@ -3,7 +3,8 @@ server.port=8101
 
 security.jwt.secret-key=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
 # 1h in millisecond
-security.jwt.expiration-time=3600000 
+security.jwt.external.expiration=3600 
+security.jwt.internal.expiration=20
 security.jwt.kid=cYz3kNRLAirxVhHXQ5rh5xKrOwHwZVui
 
 external.services.users.url=http://localhost:8201/users
\ No newline at end of file