使用 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]]
我目前正在使用 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]]