使用 Auth0 和 Apache CXF 实现 OAuth 2.0

implements OAuth 2.0 with Auth0 and Apache CXF

我目前正在使用 Auth0 和 apache CXF 开发 OAuth 2.0 令牌服务器。我的要求如下:我有两种消费者: 客户端,在 Angular2 上编写,使用 Auth0 服务流,和 服务器,写在 Java,使用客户端创建的访问令牌。

现在,我将访问令牌从客户端发送到 headers 内的服务器,它工作正常。问题是 CXF returns javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized,在尝试验证它时。

我遵循了 Apache CXF 文档并将以下代码添加到我的 beans.xml 文件中,但似乎仍然缺少某些内容。

http://cxf.apache.org/docs/jax-rs-oauth2.html#JAX-RSOAuth2-AccessTokenValidationService

<bean id="tvServiceClientFactory" class="org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean">
    <property name="address" value="https://MY_DOMAIN.auth0.com/userinfo"/>
    <property name="headers">
        <map>
            <entry key="Accept" value="application/json"/>
            <entry key="Content-Type" value="application/x-www-form-urlencoded"/>
        </map>
    </property>
</bean>

<bean id="tvServiceClient" factory-bean="tvServiceClientFactory" factory-method="createWebClient"/>

<bean id="tokenValidator" class="org.apache.cxf.rs.security.oauth2.filters.AccessTokenValidatorClient">
    <property name="tokenValidatorClient" ref="tvServiceClient"/>
</bean>

<bean id="oauthFilter" class="org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter">
    <property name="tokenValidator" ref="tokenValidator"/>
</bean>
<!-- / CXF Auth2.0 Filters -->

<jaxrs:server id="services" address="/PartMfg">
    <jaxrs:serviceBeans>
        <bean class="MY_SERVICE"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider"/>
        <ref bean="oauthFilter"/>
    </jaxrs:providers>
</jaxrs:server>

我尝试在 Postman 上验证访问令牌,得到的响应代码为 200,因此令牌本身没有问题。

我错过了什么?

好的,我明白了。 CXF 验证器 class 期望对 return 特定 class 的响应。 Auth0 服务 return 是一个 Json 和用户信息。

我所做的是创建我自己的过滤器class,它继承了 OAuthRequestFilter 的形式。

    public void filter(ContainerRequestContext context) {
    // Try to get authenticate and get user info
    WebClient webClient = WebClient.create(https://YOUR_AUTH_DOMAIN/userinfo);
    webClient.type("application/json").accept("application/json");
    String token = context.getHeaderString("Authorization");
    webClient.header("Authorization", token);
    Response response = webClient.get();
    // Check if authorized
    if (!(response.getStatus() == Response.Status.OK.getStatusCode() || response.getStatus() == Response.Status.NO_CONTENT.getStatusCode()
            || response.getStatus() == Response.Status.TEMPORARY_REDIRECT.getStatusCode())) {
        AuthorizationUtils.throwAuthorizationFailure(this.supportedSchemes, this.realm);
    }
[[REST OF YOUR HANDLE]]