Versiones comparadas

Clave

  • Se ha añadido esta línea.
  • Se ha eliminado esta línea.
  • El formato se ha cambiado.

Para recibir el token en nuestro método REST, lo haremos en el header auth-token de la petición, y lo especificaremos en nuestros métodos Java con @RequestHeader, y podemos comprobarlo de la siguiente manera:

Bloque de código
languagejava
@GetMapping("/titulaciones")
public ResponseEntity<List<TitulacionDTO>> titulaciones(@RequestHeader(value="auth-token", required = true) String tokenCodificado) {
	// Comprobamos el token
	try {
		jwtTokenUtil.getClaim( tokenCodificado );
	} catch( final ServicioException e ) {
		log.error( e.getLocalizedMessage() );
		return new ResponseEntity<>( HttpStatus.FORBIDDEN );
	}
}

Dentro de estos métodos tendremos que comprobar el token, devolviendo forbidden (ResponseEntity<>(HttpStatus.FORBIDDEN)) si no es correcto. Para comprobarlo, podemos utilizar la siguiente clase:

Bloque de código
languagejava
@Component
public class JwtTokenUtil {
 
	private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager
			.getLogger( JwtTokenUtil.class );
 
	@Value( "${es.um.jwt.secret}" )
	private String secret;
 
	// In minutes
	@Value( "${es.um.jwt.expires}" )
	private long expires;
 
	@Value( "${es.um.jwt.expiresImpersonation}" )
	private long expiresImpersontion;
 
	/**
	 * Get the claim from the token If token expirated throw TokenExpiredException If token is invalid throw
	 * UnauthorizedException
	 */
	public Claims getClaim( String token ) {
		try {
			final Claims claims = Jwts.parser().setSigningKey( TextCodec.BASE64.encode( secret ) )
					.parseClaimsJws( token ).getBody();
			JwtTokenUtil.log.debug( "El claims es: " + claims.toString() );
			JwtTokenUtil.log.debug( "El subject es: " + claims.getSubject() );
 
			final Date expiration = claims.getExpiration();
			if ( Instant.now().isAfter( expiration.toInstant() ) ) {
				JwtTokenUtil.log.error( "Expiration Date: " + expiration.toString() );
				JwtTokenUtil.log.error( "Current Instant: " + Instant.now().toString() );
				JwtTokenUtil.log.error( "Error el token " + token + " está caducado" );
				throw new TokenExpiredException();
			}
 
			return claims;
 
		} catch ( final JwtException e ) {
			JwtTokenUtil.log.error( "Error filtering:" + e );
			throw new UnauthorizedException();
		}
	}
}

Como vemos, tiene que ir anotada con @Component, y después la instanciaremos en nuestro controlador REST con @Autowired. También vemos que cogemos el valor del secret y de cuándo expira de nuestro application.properties. Podemos ver cómo funciona la parametrización en esta página de la wiki.

El secret lo utilizamos para decodificar el token, y obtenemos un objeto de tipo Claims. Podemos ver la información que contiene con toString(), pero lo más importante es obtener el email del usuario logeado, que lo haremos con .getSubject().

Si el token no es válido, o si ha expirado, se lanza una excepción. Para ello nos hemos definido excepciones propias, en un paquete exceptions. Las clases correspondientes son las siguientes:

ServicioException.java


Bloque de código
languagejava
/**
 * ServicioNotFoundException
 */
public class ServicioException extends RuntimeException {
 
	private static final long serialVersionUID = 1L;
 
	private static final HttpStatus status = HttpStatus.BAD_REQUEST;
 
	protected ServicioException( String msg ) {
		super( msg );
	}
 
	public HttpStatus getStatus() {
		return ServicioException.status;
	}
 
}

Token ExpiredException.java


Bloque de código
languagejava
/**
 * ServicioNotFoundException
 */
public class TokenExpiredException extends ServicioException {
 
	private static final long serialVersionUID = 1L;
 
	private static final HttpStatus status = HttpStatus.UNAUTHORIZED;
 
	public TokenExpiredException() {
		super( "Token_expired" );
	}
 
	@Override
	public HttpStatus getStatus() {
		return TokenExpiredException.status;
	}
 
}


UnauthorizedException.java


Bloque de código
languagejava
/**
 * ServicioNotFoundException
 */
public class UnauthorizedException extends ServicioException {
 
	private static final long serialVersionUID = 1L;
 
	private static final HttpStatus status = HttpStatus.UNAUTHORIZED;
 
	public UnauthorizedException() {
		super( "No tiene acceso para solicitar este servicio " );
	}
 
	@Override
	public HttpStatus getStatus() {
		return UnauthorizedException.status;
	}
 
}


Teniendo todo esto, para comprobar el token en nuestos métodos REST sólo tendremos que llamar a .getClaim(token).