Я использую технологии JAX-RS и JWT для аутентификации пользователя и предоставления доступа к сервисам, токен генерируется, но когда я использую сервис, у меня нет авторизации.
В этом примере я мог его найтив Интернете, но создание собственной реализации не работает.
В чем может быть проблема?
Квалификатор:
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
public @interface JWTTokenRequired {}
JWTHelper Класс:
public class JWTAuthHelper {
public static Key generateKey() {
String keyString = "jwttestkey";
Key key = new SecretKeySpec(keyString.getBytes(), 0, keyString.getBytes().length, "DES");
return key;
}
public static boolean isValidToken(String token) {
try {
Key key = generateKey();
Jwts.parser().setSigningKey(key).parseClaimsJws(token);
} catch (ExpiredJwtException | MalformedJwtException | SignatureException | UnsupportedJwtException
| IllegalArgumentException e) {
return false;
}
return true;
}
public static String issueToken(String login, String issuer) {
Key key = generateKey();
String jwtToken = Jwts.builder()
.signWith(SignatureAlgorithm.HS512, key)
.setSubject(login)
.setIssuer(issuer)
.setIssuedAt(new Date())
.setExpiration(toDate(LocalDateTime.now().plusMinutes(15L)))
.claim("id", login)
.compact();
return jwtToken;
}
private static Date toDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
}
JWTAuthValidationFilter Класс:
@Provider
@JWTTokenRequired
@Priority(Priorities.AUTHENTICATION)
public class JWTAuthValidationFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
System.out.println(authorizationHeader);
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
throw new NotAuthorizedException("Authorization header is missing");
}
String token = authorizationHeader.substring("Bearer
".length()).trim();
System.out.println("TOKEN " + token);
if (!JWTAuthHelper.isValidToken(token)) {
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
}
Логин:
@POST
@Path("login")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response authenticateUser(@FormParam("login") String login, @FormParam("password") String password) {
try {
String token = JWTAuthHelper.issueToken(login, uriInfo.getAbsolutePath().toString());
return Response.ok().header(AUTHORIZATION, "Bearer " + token).build();
} catch (Exception e) {
return Response.status(UNAUTHORIZED).build();
}
}
Конечная точка:
@Path("endpoint")
@Produces(MediaType.TEXT_HTML)
@Consumes(MediaType.TEXT_HTML)
@JWTTokenRequired
public class EndPoint {
@GET
@Path("hi")
public Response hi() {
String saludo = "hi from server";
return Response.status(Response.Status.OK).entity(saludo).build();
}
}
Я тестирую в основном классе:
public static void main(String[] args) {
String base = "http://localhost:8080/v1";
Client client = ClientBuilder.newClient();
WebTarget target = client.target(base).path("session/login");
Form form = new Form();
form.param("login", "123");
form.param("password", "123");
Response response = target.request(javax.ws.rs.core.MediaType.APPLICATION_JSON)
.post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
String jwt = response.getHeaderString(HttpHeaders.AUTHORIZATION);
System.out.println(jwt);
target = null;
target = client.target(base).path("endpoint/hi");
System.out.println(target.request(javax.ws.rs.core.MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, jwt).get());
client.close();
}
результат:
Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxMjMiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvdjEvc2Vzc2lvbi9sb2dpbiIsImlhdCI6MTU1ODk3MDQ4NywiZXhwIjoxNTU4OTcxMzg3LCJpZCI6IjEyMyJ9.nAZBRGFvuaBEyek7Lm66NBnkRpUWLmKr0_YXCTWCgywlGMBCcRhdjtL2C6LkUXxn4KhpcLeDhtLTnPbC5kD9JA
InboundJaxrsResponse{context=ClientResponse{method=GET, uri=http://localhost:8080/v1/endpoint/saludo, status=401, reason=Unauthorized}}
В моих зависимостях pom.xml используйте kumuluz microprofile и jjwt
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
Edit 01: я получаю тот же результат, когда я тестирую с другими клиентами rest (ARC, почтальон)