基本 Auth 授权 header 和 base 64 编码
Basic Auth Authorization header and base 64 encoding
我想与之交换数据的供应商。他们要我使用他们给我的用户名和密码,并在授权 header 上使用它来获取请求。
现在是我肮脏的小秘密。我以前从未创建过授权 header。
所以我做了很多研究并找出了以下代码。
public static final String AUTH_SEPARATOR = ":";
private static final String AUTH_TYPE = "Basic ";
public static final String HEADER_AUTHORIZATION = "Authorization";
public static void addAuthHeader(Map<String, String> headers, String user, String password) {
String secretKey = user
+ AUTH_SEPARATOR
+ password;
byte[] tokenBytes = secretKey.getBytes();
String token64 = Base64.getEncoder().encodeToString(tokenBytes);
String auth = AUTH_TYPE + token64;
headers.put(HEADER_AUTHORIZATION, auth);
}
我 运行 它,但我没有得到任何回应。嗯。所以我去向他们提出支持请求,我想创建一个示例,所以我打开邮递员并使用他们给我的 APIs 作为邮递员。首先,我 运行 用于我正在复制的 API 的那个,它可以工作。嗯。
然后我修改 API 并使用我的用户名和密码代替示例中包含的用户名和密码,它工作正常。天哪!
所以我转了一圈,注意到邮递员创建的身份验证中的 Base64 字符串最后与我创建的略有不同。
所以,回到研究,我发现的所有代码看起来很像我的代码,尽管由于版本差异我不得不更新它。字符串仍然不同,现在我正在寻求帮助。肯定有人解决了这个问题。
来自邮递员的字符串“Basic THVKZ...FvTg==”
来自“Basic THVKZ...FvTiA=”上方代码的字符串
我怎么做错了最后只有三个字节的差异?
Tg==
是 N
.
的 base64
TiA=
是 N
的 base64(如 N,然后是 space)。
太棒了,邮递员好像在上面贴了一个 space 而你没有。希望,如果您在 base64 编码的最后添加一个 space,您应该得到与邮递员给您的字符串完全相同的字符串,并且希望到那时一切都会成功: )
尊敬的开发者,他们不是在 OAuth2 上 运行 吗?如果是这样,请使用下面的代码块将其杀死
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer " + token you are either generating or getting from Eureka discovery service);
return headers;
}
AuthResponseObjectType getAuthorization() {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
String auth = basicAuthUsername + ":" + basicAuthPassword;
byte[] encodedAuth = org.apache.commons.net.util.Base64.encodeBase64(auth.getBytes(StandardCharsets.US_ASCII));
headers.add("Authorization", "Basic " + new String(encodedAuth));
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("grant_type", grantType);
map.add("username", username);
map.add("password", password);
map.add("scope", scope);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
return restTemplate.exchange(authUrl, HttpMethod.POST, request, AuthResponseObjectType.class).getBody();
}
如果您遇到任何挑战,请告诉我,我们可以一起解决
Postman 使用 UTF-8 进行基本身份验证编码,从 https://github.com/postmanlabs/postman-app-support/issues/4070
检查
像这样更改您的代码
secretKey.getBytes(StandardCharsets.UTF_8);
问题是由填充引起的。我仍然不明白为什么,但是我正在编码的字符串有 49 个字节长,不能被 3 整除,这意味着填充起作用了。
当我将代码更改为以下内容时:
String token64 = Base64.getEncoder().withoutPadding().encodeToString(tokenBytes);
然后 运行 它,我得到了相同的字符串减去 base64 用作填充字符的两个 == 末尾。将其发送到服务器得到了我正在寻找的答案。
当它这么难的时候,为什么他们称它为软件?
我想与之交换数据的供应商。他们要我使用他们给我的用户名和密码,并在授权 header 上使用它来获取请求。
现在是我肮脏的小秘密。我以前从未创建过授权 header。
所以我做了很多研究并找出了以下代码。
public static final String AUTH_SEPARATOR = ":";
private static final String AUTH_TYPE = "Basic ";
public static final String HEADER_AUTHORIZATION = "Authorization";
public static void addAuthHeader(Map<String, String> headers, String user, String password) {
String secretKey = user
+ AUTH_SEPARATOR
+ password;
byte[] tokenBytes = secretKey.getBytes();
String token64 = Base64.getEncoder().encodeToString(tokenBytes);
String auth = AUTH_TYPE + token64;
headers.put(HEADER_AUTHORIZATION, auth);
}
我 运行 它,但我没有得到任何回应。嗯。所以我去向他们提出支持请求,我想创建一个示例,所以我打开邮递员并使用他们给我的 APIs 作为邮递员。首先,我 运行 用于我正在复制的 API 的那个,它可以工作。嗯。
然后我修改 API 并使用我的用户名和密码代替示例中包含的用户名和密码,它工作正常。天哪!
所以我转了一圈,注意到邮递员创建的身份验证中的 Base64 字符串最后与我创建的略有不同。
所以,回到研究,我发现的所有代码看起来很像我的代码,尽管由于版本差异我不得不更新它。字符串仍然不同,现在我正在寻求帮助。肯定有人解决了这个问题。
来自邮递员的字符串“Basic THVKZ...FvTg==” 来自“Basic THVKZ...FvTiA=”上方代码的字符串
我怎么做错了最后只有三个字节的差异?
Tg==
是 N
.
TiA=
是 N
的 base64(如 N,然后是 space)。
太棒了,邮递员好像在上面贴了一个 space 而你没有。希望,如果您在 base64 编码的最后添加一个 space,您应该得到与邮递员给您的字符串完全相同的字符串,并且希望到那时一切都会成功: )
尊敬的开发者,他们不是在 OAuth2 上 运行 吗?如果是这样,请使用下面的代码块将其杀死
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer " + token you are either generating or getting from Eureka discovery service);
return headers;
}
AuthResponseObjectType getAuthorization() {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
String auth = basicAuthUsername + ":" + basicAuthPassword;
byte[] encodedAuth = org.apache.commons.net.util.Base64.encodeBase64(auth.getBytes(StandardCharsets.US_ASCII));
headers.add("Authorization", "Basic " + new String(encodedAuth));
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("grant_type", grantType);
map.add("username", username);
map.add("password", password);
map.add("scope", scope);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
return restTemplate.exchange(authUrl, HttpMethod.POST, request, AuthResponseObjectType.class).getBody();
}
如果您遇到任何挑战,请告诉我,我们可以一起解决
Postman 使用 UTF-8 进行基本身份验证编码,从 https://github.com/postmanlabs/postman-app-support/issues/4070
检查像这样更改您的代码
secretKey.getBytes(StandardCharsets.UTF_8);
问题是由填充引起的。我仍然不明白为什么,但是我正在编码的字符串有 49 个字节长,不能被 3 整除,这意味着填充起作用了。
当我将代码更改为以下内容时:
String token64 = Base64.getEncoder().withoutPadding().encodeToString(tokenBytes);
然后 运行 它,我得到了相同的字符串减去 base64 用作填充字符的两个 == 末尾。将其发送到服务器得到了我正在寻找的答案。
当它这么难的时候,为什么他们称它为软件?