Java 无法将Spring集成连接到RestTemplate
我是一个具有Spring集成框架的完整noob 我正在尝试使用一个使用OAuth2的RESTAPI。我使用的是基于xml的Spring集成配置 我的问题是,似乎无法正确连接网关和Rest模板以发送令牌请求的正文(多部分) 这在我的spring集成配置文件中: spring集成上下文.xmlJava 无法将Spring集成连接到RestTemplate,java,spring,spring-security,spring-integration,spring-security-oauth2,Java,Spring,Spring Security,Spring Integration,Spring Security Oauth2,我是一个具有Spring集成框架的完整noob 我正在尝试使用一个使用OAuth2的RESTAPI。我使用的是基于xml的Spring集成配置 我的问题是,似乎无法正确连接网关和Rest模板以发送令牌请求的正文(多部分) 这在我的spring集成配置文件中: spring集成上下文.xml <!-- Rest Template --> <bean id="oAuth2RestTemplate" class="org.springframework.security.
<!-- Rest Template -->
<bean id="oAuth2RestTemplate"
class="org.springframework.security.oauth2.client.OAuth2RestTemplate">
<constructor-arg ref="clientCredentialsResource"/>
</bean>
<!-- Used by Rest Template -->
<bean id= "clientCredentialsResource"
class="org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails">
<property name="clientId" value="${oauth2.clientId}" />
<property name="clientSecret" value="${oauth2.clientSecret}" />
<property name="accessTokenUri" value="${oauth2.accessTokenUri}" />
</bean>
<!-- Channels for requesting token -->
<int:channel id="tokenRequestChannel"/>
<int:channel id="tokenResponseChannel"/>
<!-- Gateway for requesting token -->
<int-http:outbound-gateway id="authRequestGateway"
request-channel="tokenRequestChannel"
url="${oauth2.endPointUri}"
reply-timeout="30000"
http-method="GET"
rest-template="oAuth2RestTemplate"
reply-channel="tokenResponseChannel"
charset="UTF-8"
expected-response-type="java.lang.String">
</int-http:outbound-gateway>
<!-- Add Payload -->
<int:inbound-channel-adapter id="oauth2ChannelAdapter" channel="preTokenRequestChannel"
ref="grantAndScope" method="getGrantTypeAndScope">
<!-- Triggering requests every 5 seconds -->
<int:poller fixed-delay="5000" />
</int:inbound-channel-adapter>
<!-- POJO with Grant & Scope Payload -->
<bean id="grantAndScope" class="com.AuthTypeAndScopeInfo"/>
<!-- Adding headers for Token Request -->
<int:header-enricher input-channel="preTokenRequestChannel"
output-channel="tokenRequestChannel">
<int:header name="Authorization" value="Basic <clientId:clientSecret>"/>
<int:header name="Content-Type" value="application/x-www-form-urlencoded"/>
</int:header-enricher>
<!-- Channels for requesting token -->
<int:channel id="tokenRequestChannel"/>
<int:channel id="tokenResponseChannel"/>
<!-- Channels for Authenticated requests (with valid token) -->
<int:channel id="authenticatedRequestChannel"/>
<int:channel id="authenticatedResponseChannel"/>
<!-- Gateway for requesting token -->
<!-- REST request to authorization server for a token -->
<!-- replies time out after 30 seconds -->
<int-http:outbound-gateway id="tokenRequestGateway"
request-channel="tokenRequestChannel"
url="${security.oauth2.client.accessTokenUri}"
reply-timeout="30000"
http-method="POST"
reply-channel="tokenResponseChannel"
charset="UTF-8"
expected-response-type="java.lang.String">
</int-http:outbound-gateway>
<!-- Adding headers for Authenticated Request (contains newly obtained token) -->
<int:chain input-channel="tokenResponseChannel"
output-channel="authenticatedRequestChannel">
<int:header-enricher>
<!-- Adds token_type and the actual (authenticated)
access_token to the header of the next request
(overwriting the Basic <...> previous entry) -->
<int:header name="Authorization" overwrite="true"
expression="#jsonPath(payload,'$.token_type') + ' ' + #jsonPath(payload,'$.access_token')" />
</int:header-enricher>
</int:chain>
<!-- REST request with pre-authorized token -->
<!-- replies time out after 30 seconds -->
<int-http:outbound-gateway id="authenticatedRequestGateway"
request-channel="authenticatedRequestChannel"
url="${security.oauth2.client.endPointUri}"
reply-timeout="30000"
http-method="GET"
reply-channel="authenticatedResponseChannel"
charset="UTF-8"
expected-response-type="java.lang.String">
</int-http:outbound-gateway>
API要求字符串grant\u type=client\u credentials&scope=read
位于请求的主体(而不是URL),因为这是POST
(而不是GET
)
我尝试了几件事情(太多了,记不住/重新叙述了所有事情),但我不确定在哪里/如何将有效负载放入我的请求中。
我错过了一些东西(很明显?),我不知道这是什么
这是我在日志中得到的信息(请求/响应):
2016-11-10 16:46:22.429调试6384---[ask-scheduler-3]
s、 n.www.protocol.http.HttpURLConnection:
太阳网。MessageHeader@2d1f9cc810成对:{POST
[redact]/oauth/token HTTP/1.1:null}{授权:基本
[修订]}{接受:
application/json,application/x-www-form-urlencoded}{内容类型:
application/x-www-form-urlencoded}{Cache-Control:no Cache}{Pragma:
无缓存}{用户代理:Java/1.8.0_72}{主机:
[修订]}{连接:保持活动状态}{内容长度:29}
2016-11-10 16:46:22.584调试6384---[ask-scheduler-3]
s、 n.www.protocol.http.HttpURLConnection:
太阳网。MessageHeader@29200db310对:{null:HTTP/1.1400坏
请求}{缓存控制:无缓存}{Pragma:无缓存}{内容类型:
application/json;charset=utf-8}{Expires:-1}{Server:
[修订]}{[修订]}{[修订]}{日期:2016年11月11日星期五00:46:48 GMT}{内容长度:46}
2016-11-10 16:46:22.586错误6384---[ask-scheduler-3]
o、 s.integration.handler.LoggingHandler:
org.springframework.messaging.MessageHandlingException:HTTP请求
URI的执行失败
[修订];
嵌套异常为error=“access\u denied”,error\u description=“access
令牌被拒绝。“在
org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.HandlerRequestMessage(HttpRequestExecutingMessageHandler.java:409)
在
org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
在
org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
在
org.springframework.integration.dispatcher.AbstractDispatcher.tryoOptimizedDispatch(AbstractDispatcher.java:116)
在
org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
在
org.springframework.integration.dispatcher.UnicastingDispatcher.dispatcher(UnicastingDispatcher.java:121)
在
org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
在
org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
在
org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
在
org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
在
org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
在
org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
在
org.springframework.integration.endpoint.SourcePollingChannelAdapter.handleMessage(SourcePollingChannelAdapter.java:195)
在
org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:272)
在
org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:58)
在
org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:190)
在
org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:186)
在
org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:353)
在
org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
在
org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
在
org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
在
org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
在
org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
在
org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
在
Executors$RunnableAdapter.call(Executors.java:511)
在java.util.concurrent.FutureTask.run(FutureTask.java:266)处
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
在
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
在
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
在
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
在java.lang.Thread.run(Thread.java:745)处,由以下原因引起:
error=“access\u denied”,error\u description=“access token denied。”
org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:142)
在
org.springframework.security.oauth2.client.token.grant.ClientCredentialsAccessTokenProvider.obtainAccessTo
grant_type=client_credentials&scope=read
<!-- Add Payload -->
<int:inbound-channel-adapter id="oauth2ChannelAdapter" channel="tokenRequestChannel"
ref="grantAndScope" method="getGrantTypeAndScope">
<!-- Triggering requests every 5 seconds -->
<int:poller fixed-delay="5000" />
</int:inbound-channel-adapter>
<!-- Bean with Grant & Scope Payload -->
<bean id="grantAndScope" class="com.AuthTypeAndScopeInfo"/>
public class AuthTypeAndScopeInfo {
/* adds grant type and scope as body to message */
public MultiValueMap<String, String> getGrantTypeAndScope() {
// Create the request body as a MultiValueMap
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
body.add("grant_type", "client_credentials");
body.add("scope", "read");
return body;
}
}
public class AuthTypeAndScopeInfo {
/* adds grant type and scope as body to message */
public MultiValueMap<String, String> getGrantTypeAndScope() {
// Create the request body as a MultiValueMap
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
body.add("grant_type", "client_credentials");
body.add("scope", "read");
return body;
}
}
<!-- Add Payload -->
<int:inbound-channel-adapter id="oauth2ChannelAdapter" channel="preTokenRequestChannel"
ref="grantAndScope" method="getGrantTypeAndScope">
<!-- Triggering requests every 5 seconds -->
<int:poller fixed-delay="5000" />
</int:inbound-channel-adapter>
<!-- POJO with Grant & Scope Payload -->
<bean id="grantAndScope" class="com.AuthTypeAndScopeInfo"/>
<!-- Adding headers for Token Request -->
<int:header-enricher input-channel="preTokenRequestChannel"
output-channel="tokenRequestChannel">
<int:header name="Authorization" value="Basic <clientId:clientSecret>"/>
<int:header name="Content-Type" value="application/x-www-form-urlencoded"/>
</int:header-enricher>
<!-- Channels for requesting token -->
<int:channel id="tokenRequestChannel"/>
<int:channel id="tokenResponseChannel"/>
<!-- Channels for Authenticated requests (with valid token) -->
<int:channel id="authenticatedRequestChannel"/>
<int:channel id="authenticatedResponseChannel"/>
<!-- Gateway for requesting token -->
<!-- REST request to authorization server for a token -->
<!-- replies time out after 30 seconds -->
<int-http:outbound-gateway id="tokenRequestGateway"
request-channel="tokenRequestChannel"
url="${security.oauth2.client.accessTokenUri}"
reply-timeout="30000"
http-method="POST"
reply-channel="tokenResponseChannel"
charset="UTF-8"
expected-response-type="java.lang.String">
</int-http:outbound-gateway>
<!-- Adding headers for Authenticated Request (contains newly obtained token) -->
<int:chain input-channel="tokenResponseChannel"
output-channel="authenticatedRequestChannel">
<int:header-enricher>
<!-- Adds token_type and the actual (authenticated)
access_token to the header of the next request
(overwriting the Basic <...> previous entry) -->
<int:header name="Authorization" overwrite="true"
expression="#jsonPath(payload,'$.token_type') + ' ' + #jsonPath(payload,'$.access_token')" />
</int:header-enricher>
</int:chain>
<!-- REST request with pre-authorized token -->
<!-- replies time out after 30 seconds -->
<int-http:outbound-gateway id="authenticatedRequestGateway"
request-channel="authenticatedRequestChannel"
url="${security.oauth2.client.endPointUri}"
reply-timeout="30000"
http-method="GET"
reply-channel="authenticatedResponseChannel"
charset="UTF-8"
expected-response-type="java.lang.String">
</int-http:outbound-gateway>