我已经设置了一个消费者应用程序,大多数oauth工作流看起来都是正确的,但由于某种原因,在提供者调用回调url后,它会两次尝试获取访问令牌。第一次工作
http://localhost:8080/app/ws/oauth/token[OAuth OAuth_consumer_key="itd79n64zlwv5hhv",OAuth_nonce="cac26978-c36c-4a8b-8f3e-3e779ff927ab",oaauth_signature="5c8BM9qQoijXC2f5IXpQGtSQys%3D",oaAuth_signatures_method="HMAC-SHA1",oaout_timestamp="1458938403",oath_token="5451cf20-7eed-4797-819c-ee2316981654",oaut_verifier="c56de55-79df-455e-abb87-f5f11b1b 953ef",OAuth_version="1.0"]
响应是200,有效载荷包括oauth_token=a95d6305-4261-4c1d-a9b0-43411a0c2f2c&oauth_token_secret=573702d2-70ca-412c-84e5-868e9ee07169
但是随后,它再次调用URL。
http://localhost:8080/app/ws/oauth/token[OAuth OAuth_consumer_key="itd79n64zlwv5hhv",OAuth_nonce="6c013ef9-2f3c-49dd-84fb-97bb73b5fb39",oaauth_signature="5RTQE5XtcqUwEFVvYQjExhH1eio%3D",oaAuth_signatures_method="HMAC-SHA1",oaut_timestamp="1458938403",oath_token="5451cf20-7eed-4797-819c-ee2316981654",oaout_verifier="c56de55-79df-455e-ab87-f 5f11b953ef",OAuth_version="1.0"
这在服务器上引起异常,因为请求令牌已经被移除并且访问令牌已经被发布。
在遍历代码时,我可以看到OAuthConsumerContentFilter在第一次调用后会很好地存储访问令牌。
不知怎的,过滤器链最终将其带回到CoreOAuthConsumerSupport中的readResource,并带有请求令牌。
我使用spring-boot构建了消费者应用程序。
来自:applicationContext.xml
<bean id="oscarService" class="com.mdumontier.oscar.labline.service.OscarService">
<property name="oscarRestTemplate">
<bean class="org.springframework.security.oauth.consumer.client.OAuthRestTemplate">
<constructor-arg ref="oscar" />
</bean>
</property>
</bean>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="marissa" password="wombat" authorities="ROLE_USER" />
<security:user name="sam" password="kangaroo" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<security:http auto-config='true' >
</security:http>
<oauth:consumer resource-details-service-ref="resourceDetails" oauth-failure-page="/oauth_error.jsp">
<oauth:url pattern="/oscar/**" resources="oscar"/>
</oauth:consumer>
<oauth:resource-details-service id="resourceDetails">
<oauth:resource id="oscar"
key="itd79n64zlwv5hhv"
secret="d3psvmrn8k1xws9x"
request-token-url="http://localhost:8080/app/ws/oauth/initiate"
user-authorization-url="http://localhost:8080/app/ws/oauth/authorize"
access-token-url="http://localhost:8080/app/ws/oauth/token"/>
</oauth:resource-details-service>
Spring Boot会自动在主应用程序过滤器链中注册任何实现Filter的Bean。请参阅:https://stackoverflow.com/a/28428154了解更多细节。
使用者助手将两个oauth过滤器都注册为bean,并且似乎有一段时间没有更新。我甚至无法让XML配置在最新的Spring Boot下正常工作。无论如何,这意味着两者都将运行两次,在OAuthConsumerContentFilter的情况下,这是破坏性的,因为它将在安全子链之外运行,每次都会失败。
要解决此问题,您有两种选择。
首先,提示Spring Boot通过为它自动拾取的每个过滤器提供FilterRegistrationBean来避免这种行为,如下所示:
@Bean
public FilterRegistrationBean registration(OAuthConsumerContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}
第二,完全绕过XML配置,使用Java配置。我发布了一个完整的工作代码示例,在Spring Boot中使用Java配置获取OAuth 1消费者,答案如下:https://stackoverflow.com/a/42143001/2848158
在Java配置中,您必须重复FilterRegistrationBean技巧,或者首先不将这些过滤器注册为bean,而是直接使用Security过滤器链创建和注册实例。