Я пытаюсь создать JAX-RS Rest API с Джерси.Я придерживаюсь самого популярного ответа из этой темы: Рекомендации по аутентификации на основе токенов REST с JAX-RS и Джерси
Я получил Идентификация текущегопользователь часть.Я пытаюсь использовать CDI.
Вот мой основной класс приложения:
public class Main {
// Base URI the Grizzly HTTP server will listen on
public static final String BASE_URI = "http://localhost:8080/myapp/";
/**
* Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
* @return Grizzly HTTP server.
*/
public static HttpServer startServer() {
// create a resource config that scans for JAX-RS resources and providers
// in appServer package
final ResourceConfig rc = new ResourceConfig().packages("appServer");
rc.register(new CORSFilter());
rc.register(new AuthenticationFilter());
// create and start a new instance of grizzly http server
// exposing the Jersey application at BASE_URI
return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc, false);
}
/**
* Main method.
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
final Weld weld = new Weld();
weld.initialize();
final HttpServer server = startServer();
server.start();
new SessionUtil().buildSession(args);
System.out.println(String.format("Jersey app started with WADL available at "
+ "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
System.in.read();
server.stop();
weld.shutdown();
}
}
и соответствующий класс фильтра:
import appServer.AuthenticatedUser;
import appServer.Secured;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import javax.annotation.Priority;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Event;
import javax.enterprise.inject.Default;
import javax.inject.Inject;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
private static final String REALM = "myRealm";
private static final String AUTHENTICATION_SCHEME = "Bearer";
public AuthenticationFilter() {
super();
}
@Inject
@AuthenticatedUser
Event<String> userAuthenticatedEvent;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// Get the Authorization header from the request
String authorizationHeader =
requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// Validate the Authorization header
if (!isTokenBasedAuthentication(authorizationHeader)) {
abortWithUnauthorized(requestContext);
return;
}
// Extract the token from the Authorization header
String token = authorizationHeader
.substring(AUTHENTICATION_SCHEME.length()).trim();
try {
// Validate the token
validateToken(token);
// if successful, fire event with token
userAuthenticatedEvent.fire(token);
} catch (Exception e) {
abortWithUnauthorized(requestContext);
}
}
private boolean isTokenBasedAuthentication(String authorizationHeader) {
// Check if the Authorization header is valid
// It must not be null and must be prefixed with "Bearer" plus a whitespace
// The authentication scheme comparison must be case-insensitive
return authorizationHeader != null && authorizationHeader.toLowerCase()
.startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");
}
private void abortWithUnauthorized(ContainerRequestContext requestContext) {
// Abort the filter chain with a 401 status code response
// The WWW-Authenticate header is sent along with the response
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE,
AUTHENTICATION_SCHEME + " realm=\"" + REALM + "\"")
.build());
}
private void validateToken(String token) throws Exception {
// Check if the token was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
}
Когда я запускаю приложениепроисходит сбой с этой ошибкой:
org.glassfish.hk2.api.UnsatisfiedDependencyException: не было объекта, доступного для внедрения в SystemInjecteeImpl (requiredType = событие, родительский = AuthenticationFilter, qualifiers = {@ javax.enterprise).inject.Default (), @ appServer.AuthenticatedUser ()}, позиция = -1, необязательно = false, self = false, unqualified = null, 997918120)
Я сталкивался с этим вопросом: Как использовать события CDI в Java-Джерси? но не было никакого соответствующего ответа.Я пробовал другие решения, опубликованные для подобных проблем, но ни одно из них не сработало.
Итак, это, очевидно, какая-то проблема с инъекцией здесь:
@AuthenticatedUser
@Inject
Event<String> userAuthenticatedEvent;
Или, возможно, я не регистрируюФильтруйте правильно.Есть предложения?