code:
```
@Override
@Cacheable("tokenStoreKey")
// @SuppressWarnings({"unchecked", "rawtypes"})
public Map
OUT:
`2017-06-14 09:21:43.380 ERROR 75940 --- [nio-8088-exec-2] c.x.r.c.b.s.impl.TokenStoreServiceImpl : {"exp":1497404422,"user_name":"xzf","authorities":["CORE_BSC","CORE_TIK"],"client_id":"myclient","scope":["read","write"]}
2017-06-14 09:21:57.850 ERROR 75940 --- [nio-8088-exec-2] c.x.r.c.b.s.impl.TokenStoreServiceImpl : {"user_name":"xzf","scope":"write","exp":"1497404422","authorities":"CORE_TIK","client_id":"myclient"}`
I think this may be a BUG, and perhaps I did not find the right way
**Comment From: wilkinsona**
@xiezhaofeng Unfortunately, I can't really tell what's going on from the information you've provided. It's not clear that the two requests that you have made are equivalent. For example, what's the value of the `tokenName` local variable? I also can't tell what `Request` is, what `JSONUtil.toJackson(map)` does, or how you have configured your REST template.
If you'd like us to investigate further, please provide a complete sample that reproduces the problem.
**Comment From: xiezhaofeng**
@wilkinsona
Rest template When formatting data, there is no complete data retention.
1,`tokenName` variable value is "token".
2,`JSONUtil.toJackson (map)` is the map object into a JSON string.
Code Sample Reference: `org.springframework.security.oauth2.provider.token.RemoteTokenServices.loadAuthentication`, I rewrite this class.
The purpose of this code is to request a token from the OAUTH server. The data returned by the server should be`{"Exp": 1497404422, "user_name": "xzf", "authorities": "" CORE_BSC "," CORE_TIK "]," client_id ":" myclient "," scope ": [" read "," write " }`
REST template parsed into`{"user_name":"xzf","scope":"write","exp":"1497404422","authorities":"CORE_TIK","client_id":"myclient"}` Very confused. I do not know if this statement is clear?
TokenStoreServiceImpl.java
@Service public class TokenStoreServiceImpl implements TokenStoreService { private @Value("${security.oauth2.resource.client-id}") String clientId; private @Value("${security.oauth2.resource.client-secret}") String clientSecret; private @Value("${security.oauth2.resource.tokenInfoUri}") String tokenInfoUri;
private@Autowired RestOperations restTemplate;
private static Logger logger = LoggerFactory.getLogger(TokenStoreServiceImpl.class);
@Override
// @Cacheable("tokenStoreKey")
public Map
Map map = restTemplate.exchange("http://myserver/oauth/check_token", HttpMethod.POST, new HttpEntity<MultiValueMap<String, String>>(formData, headers),
new HashMap<String, Object>().getClass()).getBody();
logger.error(objectMapper.writeValueAsString(map));
return objectMapper.readValue(asString, objectMapper.getTypeFactory().constructMapLikeType(HashMap.class, String.class, Object.class));
}
private String getAuthorizationHeader(String clientId, String clientSecret) {
if(clientId == null || clientSecret == null) {
logger.warn("Null Client ID or Client Secret detected. Endpoint that requires authentication will reject request with 401 error.");
}
String creds = String.format("%s:%s", clientId, clientSecret);
try {
return "Basic " + new String(Base64.encode(creds.getBytes("UTF-8")));
}
catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Could not convert String");
}
}
}
CoachRemoteTokenServices.java
@Service @Primary @Qualifier public class CoachRemoteTokenServices extends RemoteTokenServices { protected final Log logger = LogFactory.getLog(getClass());
private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
private @Autowired TokenStoreService tokenStoreService;
@Override
public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException {
Map<String, Object> map = tokenStoreService.postForMap(accessToken);
if (map.containsKey("error")) {
logger.debug("check_token returned error: " + map.get("error"));
throw new InvalidTokenException(accessToken);
}
Assert.state(map.containsKey("client_id"), "Client id must be present in response from auth server");
OAuth2Authentication auth = tokenConverter.extractAuthentication(map);
auth.setAuthenticated(true);
return auth;
}
@Override
public OAuth2AccessToken readAccessToken(String accessToken) {
throw new UnsupportedOperationException("Not supported: read access token");
}
}
```
Comment From: wilkinsona
Thank you, @xiezhaofeng. That helps a little but it's still not clear exactly what needs to be done to reproduce the problem that you're seeing. Can you please share a complete sample (something that we can git clone or unzip and run) that reproduces the problem?
Comment From: xiezhaofeng
@wilkinsona Thank you for your concern, I am sorry that my ability to express is not very good, the following is the project git address.
git addr:git@github.com:xiezhaofeng/token-service.git
The exception occurs at com.xunxintech.ruyue.coach.base.service.impl.TokenStoreServiceImpl.postForMap()
Comment From: wilkinsona
@xiezhaofeng Thanks for the code but it's not clear how to use it to reproduce the problem. What do I need to do once I've run it to trigger the failure that you've described?
Comment From: xiezhaofeng
@wilkinsona To confirm whether you can visit http://rycoachtest.xunxintech.com/oauth/check_token?token=af5f282e-7751-4733-a575-9d555c791708
, if not, you may need to do some extra things.
Comment From: xiezhaofeng
@wilkinsona This is a springboot project, run directly RyCoachTicketServiceApplication.main (), if the jar package is no problem.
Comment From: wilkinsona
This looks like user error to me. The two requests that are being made (one with Apache's HTTP client and one with RestTemplate) differ in a number of ways. The main differences is that the Apache client is making a GET request and RestTemplate is making a POST request. The GET request is producing a JSON response while the POST request is producing an XML response. In neither case have you set an Accept
header in the request so you are relying on what the client requests by default and what the server will produce as a result of content negotiation.
I believe that making the POST request with an Accept: application/json
header will resolve the problem. If that does not help, please ask any follow-up questions on Stack Overflow.
Comment From: xiezhaofeng
@wilkinsona thank you, I learned again.
Comment From: lltx
thank you, I learned again too