Spring Boot 3 - Buenas prácticas y protección: Aula 4
This commit is contained in:
parent
d2d56e2a91
commit
066b2be064
@ -71,6 +71,12 @@
|
|||||||
<artifactId>spring-security-test</artifactId>
|
<artifactId>spring-security-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>java-jwt</artifactId>
|
||||||
|
<version>4.4.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -2,6 +2,9 @@ package med.voll.api.controller;
|
|||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import med.voll.api.domain.usuario.DatosAutenticacionUsuario;
|
import med.voll.api.domain.usuario.DatosAutenticacionUsuario;
|
||||||
|
import med.voll.api.domain.usuario.Usuario;
|
||||||
|
import med.voll.api.infra.security.DatosJWTtoken;
|
||||||
|
import med.voll.api.infra.security.TokenService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
@ -19,17 +22,17 @@ public class AutenticacionController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseEntity autenticarUsuario(@RequestBody @Valid DatosAutenticacionUsuario datosAutenticacionUsuario) {
|
public ResponseEntity autenticarUsuario(@RequestBody @Valid DatosAutenticacionUsuario datosAutenticacionUsuario) {
|
||||||
Authentication token = new UsernamePasswordAuthenticationToken(
|
Authentication authtoken = new UsernamePasswordAuthenticationToken(
|
||||||
datosAutenticacionUsuario.login(),
|
datosAutenticacionUsuario.login(),
|
||||||
datosAutenticacionUsuario.clave());
|
datosAutenticacionUsuario.clave());
|
||||||
authenticationManager.authenticate(token);
|
var usuarioAutenticado = authenticationManager.authenticate(authtoken);
|
||||||
//var token = new UsernamePasswordAuthenticationToken(
|
var JWTtoken = tokenService.generarToken((Usuario) usuarioAutenticado.getPrincipal());
|
||||||
// datosAutenticacionUsuario.login(),
|
return ResponseEntity.ok(new DatosJWTtoken(JWTtoken));
|
||||||
// datosAutenticacionUsuario.clave());
|
|
||||||
//var autentication = authenticationManager.authenticate(token);
|
|
||||||
return ResponseEntity.ok().build();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
package med.voll.api.infra.security;
|
||||||
|
|
||||||
|
public record DatosJWTtoken(String jwTtoken) {
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package med.voll.api.infra.security;
|
||||||
|
|
||||||
|
import com.auth0.jwt.JWT;
|
||||||
|
import com.auth0.jwt.algorithms.Algorithm;
|
||||||
|
import com.auth0.jwt.exceptions.JWTCreationException;
|
||||||
|
import med.voll.api.domain.usuario.Usuario;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TokenService {
|
||||||
|
|
||||||
|
@Value("${api.security.secret}")
|
||||||
|
private String apiSecret;
|
||||||
|
|
||||||
|
public String generarToken(Usuario usuario) {
|
||||||
|
try {
|
||||||
|
Algorithm algorithm = Algorithm.HMAC256(apiSecret) ;
|
||||||
|
return JWT.create()
|
||||||
|
.withIssuer("voll med")
|
||||||
|
.withSubject(usuario.getLogin())
|
||||||
|
.withClaim("id", usuario.getId())
|
||||||
|
.withExpiresAt(generarFechaExpiracion())
|
||||||
|
.sign(algorithm);
|
||||||
|
} catch (JWTCreationException exception){
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instant generarFechaExpiracion() {
|
||||||
|
return LocalDateTime.now().plusHours(2).toInstant(ZoneOffset.of("-03:00"));
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
# suppress inspection "SpellCheckingInspection" for whole file
|
# suppress inspection "SpellCheckingInspection" for whole file
|
||||||
spring.datasource.url=jdbc:mysql://192.168.0.8/vollmed_api2
|
spring.datasource.url=jdbc:mysql://${DB_URL}/vollmed_api2
|
||||||
spring.datasource.username=alura
|
spring.datasource.username=${DB_USER}
|
||||||
spring.datasource.password=alura
|
spring.datasource.password=${DB_PASS}
|
||||||
|
|
||||||
spring.jpa.show-sql=true
|
spring.jpa.show-sql=true
|
||||||
spring.jpa.properties.hibernate.format_sql=true
|
spring.jpa.properties.hibernate.format_sql=true
|
||||||
|
|
||||||
server.error.include-stacktrace=never
|
server.error.include-stacktrace=never
|
||||||
|
|
||||||
|
api.security.secret=${JWT_SECRET}
|
@ -564,3 +564,107 @@ create table usuarios(
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## JSON Web Token
|
||||||
|
|
||||||
|
[JWT](https://jwt.io) - [Repo](https://github.com/auth0/java-jwt)
|
||||||
|
|
||||||
|
Agregar dependencia a [pom.xml](./api_rest/api2/pom.xml)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>java-jwt</artifactId>
|
||||||
|
<version>4.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
Creación de clase
|
||||||
|
[TokenService](./api_rest/api2/src/main/java/med/voll/api/infra/security/TokenService.java)
|
||||||
|
en *package* [infra.security](./api_rest/api2/src/main/java/med/voll/api/infra/security/)
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class TokenService {
|
||||||
|
|
||||||
|
@Value("${api.security.secret}")
|
||||||
|
private String apiSecret;
|
||||||
|
|
||||||
|
public String generarToken(Usuario usuario) {
|
||||||
|
try {
|
||||||
|
Algorithm algorithm = Algorithm.HMAC256(apiSecret) ;
|
||||||
|
return JWT.create()
|
||||||
|
.withIssuer("voll med")
|
||||||
|
.withSubject(usuario.getLogin())
|
||||||
|
.withClaim("id", usuario.getId())
|
||||||
|
.withExpiresAt(generarFechaExpiracion())
|
||||||
|
.sign(algorithm);
|
||||||
|
} catch (JWTCreationException exception){
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instant generarFechaExpiracion() {
|
||||||
|
return LocalDateTime.now()
|
||||||
|
.plusHours(2)
|
||||||
|
.toInstant(ZoneOffset.of("-03:00"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Creación de propiedades manejadas por variables de entorno/ambiente
|
||||||
|
|
||||||
|
[application.properties](./api_rest/api2/src/main/resources/application.properties)
|
||||||
|
|
||||||
|
```config
|
||||||
|
spring.datasource.url=jdbc:mysql://${DB_URL}/vollmed_api2
|
||||||
|
spring.datasource.username=${DB_USER}
|
||||||
|
spring.datasource.password=${DB_PASS}
|
||||||
|
|
||||||
|
spring.jpa.show-sql=true
|
||||||
|
spring.jpa.properties.hibernate.format_sql=true
|
||||||
|
|
||||||
|
server.error.include-stacktrace=never
|
||||||
|
|
||||||
|
api.security.secret=${JWT_SECRET}
|
||||||
|
```
|
||||||
|
|
||||||
|
Creación del DTO
|
||||||
|
[DatosTokenJWT](./api_rest/api2/src/main/java/med/voll/api/infra/security/DatosJWTtoken.java)
|
||||||
|
en *package*
|
||||||
|
[infra.security](./api_rest/api2/src/main/java/med/voll/api/infra/security/)
|
||||||
|
|
||||||
|
```java
|
||||||
|
public record DatosJWTtoken(String jwTtoken) {}
|
||||||
|
```
|
||||||
|
|
||||||
|
Modificación en clase
|
||||||
|
[AutenticacionController](./api_rest/api2/src/main/java/med/voll/api/controller/AutenticacionController.java)
|
||||||
|
en *package* [controller](./api_rest/api2/src/main/java/med/voll/api/controller/)
|
||||||
|
|
||||||
|
```java
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/login")
|
||||||
|
public class AutenticacionController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public ResponseEntity autenticarUsuario(
|
||||||
|
@RequestBody @Valid DatosAutenticacionUsuario datosAutenticacionUsuario) {
|
||||||
|
Authentication authtoken = new UsernamePasswordAuthenticationToken(
|
||||||
|
datosAutenticacionUsuario.login(),
|
||||||
|
datosAutenticacionUsuario.clave());
|
||||||
|
var usuarioAutenticado = authenticationManager.authenticate(authtoken);
|
||||||
|
var JWTtoken = tokenService.generarToken(
|
||||||
|
(Usuario) usuarioAutenticado.getPrincipal()
|
||||||
|
);
|
||||||
|
return ResponseEntity.ok(new DatosJWTtoken(JWTtoken));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user