首页 > 解决方案 > 使用 CXF 向 JAX-RS 添加自定义安全上下文

问题描述

我需要将我的服务 bean 中的调用包装在自定义安全上下文中。为了稍微解耦所有内容,我不想将每个方法都包装在 中Subject.doAs(),而是更愿意找到允许我使用拦截器从请求标头中读取信息并包装后续调用的方式。

我尝试实施 aContainerRequestFilter来做到这一点。看看JAASAuthenticationFilter工作原理,我认为这样的事情应该可以工作:

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
    MultivaluedMap<String, String> headers = requestContext.getHeaders();
    Subject subject = getSubjectFromHeader(headers);
    
    // Reject request if header is missing
    if(subject == null) {
        requestContext.abortWith(Response.status(Status.BAD_REQUEST).entity("Missing header:" + HEADER_SUBJECT).build());
        return;
    }
    
    // Wrap the remaining chain is security context
    Message message = JAXRSUtils.getCurrentMessage();
    Subject.doAs(subject, new PrivilegedAction<Void>() {
           @Override
           public Void run() {
               InterceptorChain chain = message.getInterceptorChain();                
               if (chain != null) {
                   chain.doIntercept(message);
               }
               return null;
           }
       });
}

不幸的是,这似乎不适用于 JAX-RS 服务。调试问题,似乎在使用我的 RequestFilter 时,调用服务方法时没有提取和提供 Path 和 Query 参数,然后失败:

org.apache.cxf.interceptor.Fault: wrong number of arguments while invoking public a.b.c.dtos.ToDoOutDTO ch.suisa.todo.rs.impl.TodoRestServiceImpl.getTodo(java.lang.Long,java.lang.String) with params null.
    at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:167)[74:org.apache.cxf.cxf-core:3.0.4.redhat-621084]
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:141)[74:org.apache.cxf.cxf-core:3.0.4.redhat-621084]
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:200)[103:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.4.redhat-621084]
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99)[103:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.4.redhat-621084]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)[74:org.apache.cxf.cxf-core:3.0.4.redhat-621084]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)[74:org.apache.cxf.cxf-core:3.0.4.redhat-621084]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)[74:org.apache.cxf.cxf-core:3.0.4.redhat-621084]
    at ch.suisa.todo.rs.SecurityHeaderInterceptor$2.run(SecurityHeaderInterceptor.java:97)[409:phx-todo-rs:5.0.0.SNAPSHOT]
    at ch.suisa.todo.rs.SecurityHeaderInterceptor$2.run(SecurityHeaderInterceptor.java:1)[409:phx-todo-rs:5.0.0.SNAPSHOT]
    at java.security.AccessController.doPrivileged(Native Method)[:1.8.0_265]
    at javax.security.auth.Subject.doAs(Subject.java:360)[:1.8.0_265]

这是一个错误还是无法按预期工作的东西?

标签: javajbossjax-rscxfjbossfuse

解决方案


推荐阅读