我正在尝试使用spring的UriComponentsBuilder来生成一些用于oauth交互的URL。查询参数包括诸如回调URL和其中包含空格的参数值之类的实体。
尝试使用UriComponentBuilder(因为现在不推荐使用UriUtils)
UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(oauthURL);
urlBuilder.queryParam("client_id", clientId);
urlBuilder.queryParam("redirect_uri", redirectURI);
urlBuilder.queryParam("scope", "test1 test2");
String url = urlBuilder.build(false).encode().toUriString();
不幸的是,虽然scope参数中的空格已成功替换为'+',但redirect_uri参数根本不是url编码的。
,例如,
redirect_uri=https://oauth2-login-demo.appspot.com/code
应该已经结束了
redirect_uri=https%3A%2F%2Foauth2-login-demo.appspot.com%2Fcode
但未受影响。潜入代码,特别是org.springframework.web.util.HierarchicalUriComponents.Type.QUERY_PARAM.isAllowed(c):
if ('=' == c || '+' == c || '&' == c) {
return false;
}
else {
return isPchar(c) || '/' == c || '?' == c;
}
显然允许使用':'和'/'字符,这不应该是口香糖。它必须做一些其他类型的编码,虽然对于我的生活,我无法想象什么。我在这里吠叫了错误的树吗?
由于
答案 0 :(得分:20)
UriComponentsBuilder
根据RFC 3986对您的URI进行编码,第3.4节中有关URI的'query'组件特别注意。
在'query'组件中,允许使用字符'/'和':',并且不需要转义。
以'/'字符为例:'query'组件(由未转义的'?'和(可选)'#'字符明确分隔),不是分层的,'/'字符没有特殊含义。所以它不需要编码。
答案 1 :(得分:13)
String redirectURI= "https://oauth2-login-demo.appspot.com/code";
urlBuilder.queryParam("redirect_uri", URLEncoder.encode(redirectURI,"UTF-8" ));
答案 2 :(得分:1)
尝试扫描UriComponentsBuilder文档,有一个名为build(boolean encoded)的方法
示例代码1:
UriComponents uriComponents = UriComponentsBuilder.fromPath("/path1/path2").build(true);
以下是我的示例代码2:
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.scheme("https")
.host("my.host")
.path("/path1/path2").query(parameters).build(true);
URI uri= uriComponents.toUri();
ResponseEntity<MyEntityResponse> responseEntity = restTemplate.exchange(uri,
HttpMethod.GET, entity, typeRef);