JAX-RS 认证过滤器不是通过@Secured注释触发的



我遵循以下答案:使用 JAX-RS 和 Jersey 进行基于 REST 令牌的身份验证以实现 REST API 身份验证的最佳实践。 但是 JAX-RS 认证过滤器不是通过@Secured注释触发的。

我完成了通过在方法上添加@Secured来保护REST 端点的部分。

这就是我这样做的方式。

安全.java

@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Secured { }

身份验证过滤器.java

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
private static final String AUTHENTICATION_SCHEME = "Bearer";
@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 {
validateToken(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
// 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
// The "WWW-Authenticate" is sent along with the response
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE, AUTHENTICATION_SCHEME)
.build());
}
private void validateToken(String token) throws Exception {
// Check if it was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
}

我的APIS.java

@Path("api")
public class MyApis {
@GET
@Secured
@Path("me")
@Produces(MediaType.APPLICATION_JSON)
public Map<String, X500Name> whoAmI() {
return ImmutableMap.of("me", legalName);
}
// other APIs
}

当我调用/api/me时,我可以直接获得响应,而无需提供任何身份验证标头。 过滤器似乎未触发或未正确注册。

我已经看到了这个问题 JAX RS,我的过滤器不起作用,但它不能解决我的问题。

我如何理解以下内容是不需要web.xml对吗?

此解决方案仅使用 JAX-RS 2.0 API,避免了任何特定于供应商的解决方案。因此,它应该与最流行的JAX-RS 2.0实现一起使用,例如Jersey,RESTEasy和Apache CXF。

值得一提的是,如果您使用的是基于令牌的身份验证,那么您就不依赖于 servlet 容器提供的标准 Java EE Web 应用程序安全机制,并且可以通过应用程序的 web.xml 描述符进行配置。

回答迟到了,但这个问题的解决方案是将 AuthenticationFilter 添加到您的类中。

public class App extends Application { @Override public Set<Class<?>> getClasses() { final Set<Class<?>> classes = new HashSet<>(); classes.add(MyApis.class); classes.add(AuthenticationFilter.class); return classes; } }

最新更新