Apache Cxf Web 客户端在 Tomee 8 中无法按预期工作

Apache Cxf Webclient Doen't Work As Expected in Tomee 8

我正在尝试从 google 获取 jwk 密钥集以用于 Apache Cxf OIDC 和 Jose Libs。当我 运行 它在一个独立的主要方法上时,代码工作正常。

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        final WebClient client = WebClient.create("https://www.googleapis.com/oauth2/v3/certs", Arrays.asList(new JsonWebKeysProvider()), true).accept(MediaType.APPLICATION_JSON);
        JsonWebKeys keys = client.get(JsonWebKeys.class);
        keys.getKeys().forEach(key -> {
            System.out.println("****************************************************************************");
            System.out.println("ID........." + key.getKeyId());
            System.out.println("Alg........" + key.getAlgorithm());
            System.out.println("Key Type..." + key.getKeyType());
            System.out.println("Use........" + key.getPublicKeyUse());
        });

    }

}

正确打印 ID、算法、密钥类型和用途意味着密钥已 属性 填充。

示例输出:

****************************************************************************
ID.........79c809dd1186cc228c4baf9358599530ce92b4c8
Alg........RS256
Key Type...RSA
Use........sig
****************************************************************************
ID.........17d55ff4e10991d6b0efd392b91a33e54c0e218b
Alg........RS256
Key Type...RSA
Use........sig

pom.xml 主要提取物 class。

<dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-client</artifactId>
            <version>3.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-security-sso-oidc</artifactId>
            <version>3.3.5</version>
        </dependency>
    </dependencies>

但是,相同的代码在 Tomee 8 中部署时不起作用。

@WebServlet(name = "NewServlet", urlPatterns = {"/x"})
public class NewServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        PrintWriter writer = response.getWriter();

        final WebClient client = WebClient.create("https://www.googleapis.com/oauth2/v3/certs", Arrays.asList(new JsonWebKeysProvider()), true).accept(MediaType.APPLICATION_JSON);
        JsonWebKeys keys = client.get(JsonWebKeys.class);
        keys.getKeys().forEach(key -> {
            writer.println("****************************************************************************");
            writer.println("ID........." + key.getKeyId());
            writer.println("Alg........" + key.getAlgorithm());
            writer.println("Key Type..." + key.getKeyType());
            writer.println("Use........" + key.getPublicKeyUse());
        });

    }
}

当此代码在 Tomee 8 中 运行s 时,ID、算法、密钥类型和用途为空。我添加了 cxf oidc 库,jose jars 安装在 tomee/lib 文件夹中。

示例输出:

****************************************************************************
ID.........null
Alg........null
Key Type...null
Use........null
****************************************************************************
ID.........null
Alg........null
Key Type...null
Use........null

pom.xml servlet 的提取。

<dependencies>
    <dependency>
        <groupId>org.apache.tomee</groupId>
        <artifactId>javaee-api</artifactId>
        <version>8.0-3</version>
        <scope>provided</scope>
    </dependency>      
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxrs</artifactId>
        <version>${cxf.version}</version>
        <scope>provided</scope>
    </dependency> 
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-rs-security-sso-oidc</artifactId>
        <version>${cxf.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-rs-client</artifactId>
        <version>${cxf.version}</version>
        <scope>provided</scope>
    </dependency>

</dependencies>

导致此问题的原因是什么?

我意识到当在 tomee 中创建 Webclient 时,它会获取 tomee 提供的总线属性,这导致 JsonWebKeysProvider 无法被调用。

在我的例子中,下面是在 tomee 中创建客户端的正确方法。

JAXRSClientFactoryBean sf = new JAXRSClientFactoryBean();
sf.setAddress("https://www.googleapis.com/oauth2/v3/certs");
sf.setProvider(new JsonWebKeysProvider());
sf.setBus(new ExtensionManagerBus());

调用 sf.setBus(new ExtensionManagerBus()); 确保提供的 tomee values/properties 不会被提取。