private Map generateOauthToken(AuthGrantType authGrantType, String username, String password,
String clientId, String clientSecret) {
// 1. 生成token
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", authGrantType.name());
params.add("client_id", clientId);
params.add("client_secret", clientSecret);
if (authGrantType == AuthGrantType.password) {
params.add("username", username);
params.add("password", password);
}
HttpEntity<MultiValueMap<String, String>> requestEntity =
new HttpEntity<>(params, httpHeaders);
return innerRestTemplate.postForObject("http://oauth2-service/oauth/token",
requestEntity, Map.class);
}
当时把params中的client_id和client_secret写成了驼峰式命名clientId和clientSecret导致报错org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 : [no body]
具体情况原因分析:第一时间以为是事务问题,当时情况是操作了两张表,然后用
JpaTransactionManager进行管理,这里额外的进行说明一下为什么不用
@Transactional注解,因为数据库是级别是RR 当前方法又要去oauth2中登录获取用户token,数据库又没有提交,所以JpaTransactionManager进行手动提交 具体代码如下
private Integer saveUserAndOauthClient(OauthUser user, OauthClientDetails oauth2Client) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
def.setTimeout(30); // 超过30秒就回滚
TransactionStatus status = transactionManager.getTransaction(def);
try {
user = this.oauthUserRepository.save(user);
this.oauthClientDetailsRepository.save(oauth2Client);
transactionManager.commit(status);
} catch (Exception e) {
if (!status.isCompleted()) {
transactionManager.rollback(status);
}
throw new UnsupportedOperationException("保存用户信息和oauth2客户端信息到DB失败");
}
return user.getId();
}