Integrar autenticación Cognito con Floci local y soporte AWS
- Añade servicios y configuración Cognito para login web (admins) y API (scanners) - Soporta Floci cuando AWS_ENDPOINT_URL está definido; AWS real en caso contrario - Incluye bootstrap Floci, docker-compose.local.yml y carga automática en run-local.sh - Documenta arquitectura, flujos y arranque manual/IntelliJ en README - Actualiza gitignore: excluye Flutter, H2 local y artefactos generados
This commit is contained in:
+38
-13
@@ -1,6 +1,7 @@
|
||||
package mx.gob.slp.baseadminweb.web.controller;
|
||||
|
||||
import mx.gob.slp.baseadminweb.configuration.security.ApiAuthService;
|
||||
import mx.gob.slp.baseadminweb.configuration.security.ApiLoginResponse;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
@@ -9,6 +10,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@@ -24,23 +26,46 @@ public class AuthApiController {
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
|
||||
try {
|
||||
ApiAuthService.ApiLoginResponse response = apiAuthService.login(request.username(), request.password());
|
||||
return ResponseEntity.ok(Map.of(
|
||||
"success", true,
|
||||
"accessToken", response.accessToken(),
|
||||
"tokenType", response.tokenType(),
|
||||
"expiresIn", response.expiresIn(),
|
||||
"username", response.username(),
|
||||
"roles", response.roles()
|
||||
));
|
||||
ApiLoginResponse response = apiAuthService.login(request.username(), request.password());
|
||||
return ResponseEntity.ok(toAuthBody(response));
|
||||
} catch (BadCredentialsException ex) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Map.of(
|
||||
"success", false,
|
||||
"message", ex.getMessage()
|
||||
));
|
||||
return unauthorized(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/refresh")
|
||||
public ResponseEntity<?> refresh(@RequestBody RefreshRequest request) {
|
||||
try {
|
||||
ApiLoginResponse response = apiAuthService.refresh(request.refreshToken());
|
||||
return ResponseEntity.ok(toAuthBody(response));
|
||||
} catch (BadCredentialsException ex) {
|
||||
return unauthorized(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> toAuthBody(ApiLoginResponse response) {
|
||||
Map<String, Object> body = new LinkedHashMap<>();
|
||||
body.put("success", true);
|
||||
body.put("accessToken", response.accessToken());
|
||||
body.put("refreshToken", response.refreshToken());
|
||||
body.put("idToken", response.idToken());
|
||||
body.put("tokenType", response.tokenType());
|
||||
body.put("expiresIn", response.expiresIn());
|
||||
body.put("username", response.username());
|
||||
body.put("roles", response.roles());
|
||||
return body;
|
||||
}
|
||||
|
||||
private ResponseEntity<Map<String, Object>> unauthorized(String message) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Map.of(
|
||||
"success", false,
|
||||
"message", message
|
||||
));
|
||||
}
|
||||
|
||||
public record LoginRequest(String username, String password) {
|
||||
}
|
||||
|
||||
public record RefreshRequest(String refreshToken) {
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
package mx.gob.slp.baseadminweb.web.controller;
|
||||
|
||||
import mx.gob.slp.baseadminweb.domain.model.AppUser;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import mx.gob.slp.baseadminweb.web.support.WebUserView;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -15,8 +15,8 @@ public class DashboardController {
|
||||
}
|
||||
|
||||
@GetMapping("/dashboard")
|
||||
public String dashboard(@AuthenticationPrincipal AppUser user, Model model) {
|
||||
model.addAttribute("user", user);
|
||||
public String dashboard(Authentication authentication, Model model) {
|
||||
model.addAttribute("user", WebUserView.from(authentication));
|
||||
return "dashboard";
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ public class DashboardController {
|
||||
public String adminHome() {
|
||||
return "redirect:/dashboard";
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
package mx.gob.slp.baseadminweb.web.controller;
|
||||
|
||||
import mx.gob.slp.baseadminweb.application.service.PassCodeService;
|
||||
import mx.gob.slp.baseadminweb.domain.model.AppUser;
|
||||
import mx.gob.slp.baseadminweb.web.dto.PassCodeListItem;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import mx.gob.slp.baseadminweb.web.support.WebUserView;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -26,8 +26,8 @@ public class PassCodeController {
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String list(@AuthenticationPrincipal AppUser user, Model model) {
|
||||
model.addAttribute("user", user);
|
||||
public String list(Authentication authentication, Model model) {
|
||||
model.addAttribute("user", WebUserView.from(authentication));
|
||||
model.addAttribute("passCodes", passCodeService.findAll());
|
||||
return "pass-codes";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package mx.gob.slp.baseadminweb.web.support;
|
||||
|
||||
import mx.gob.slp.baseadminweb.configuration.security.AuthenticatedWebUser;
|
||||
import mx.gob.slp.baseadminweb.domain.model.AppUser;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
public record WebUserView(String username, String displayName) {
|
||||
|
||||
public static WebUserView from(Authentication authentication) {
|
||||
if (authentication == null) {
|
||||
return new WebUserView("usuario", "Usuario");
|
||||
}
|
||||
|
||||
Object principal = authentication.getPrincipal();
|
||||
if (principal instanceof AppUser appUser) {
|
||||
return new WebUserView(appUser.getUsername(), appUser.getDisplayName());
|
||||
}
|
||||
if (principal instanceof AuthenticatedWebUser webUser) {
|
||||
return new WebUserView(webUser.username(), webUser.displayName());
|
||||
}
|
||||
|
||||
String name = authentication.getName();
|
||||
return new WebUserView(name, name);
|
||||
}
|
||||
}
|
||||
@@ -45,9 +45,12 @@
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between text-gray-500 fs-7 mb-8">
|
||||
<span>Usuario demo: <strong>admin</strong></span>
|
||||
<span>Usuario: <strong>admin</strong></span>
|
||||
<span>Password: <strong>Admin123*</strong></span>
|
||||
</div>
|
||||
<div class="text-gray-500 fs-8 mb-8 text-center">
|
||||
Autenticacion via Cognito local (grupo <strong>admins</strong>)
|
||||
</div>
|
||||
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user