令牌令牌的基本身份验证似乎不符合OAuth2.0规范,该规范指定用户名和密码在使用冒号和基数64编码之前应进行URL编码。参见rfc6749
标头的创建应为:
auth_header = 'Basic' + base64 (urlEncode (client_id) + ':' + urlEncode (client_secret))
因此,从密码中分离出用户名后,需要执行URL解码步骤。
Spring只是使用BasicAuthenticationFilter来提取凭证,并且似乎没有扩展它来添加URL解码步骤的方法。
那么,这是Spring Security OAuth2的遗漏吗?如果是这样,请猜测应该提出一个错误。 我可以用具有URL解码步骤的BasicAuthenticationFilter替换它,但是有更简单的方法吗?
我当前正在使用Spring Security 5.0.5
答案 0 :(得分:-1)
Spring安全性确实符合OAuth 2.0规范。 BasicAuthenticationFilter
已涵盖您的要求。以下是代码摘录:
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
boolean debug = this.logger.isDebugEnabled();
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Basic ")) {
try {
String[] tokens = this.extractAndDecodeHeader(header, request);
assert tokens.length == 2;
过滤器读取具有基本身份验证的标头,然后提取并解码凭据。
在下面的代码中,请注意冒号的索引用作字符串定界符。
private String[] extractAndDecodeHeader(String header, HttpServletRequest request) throws IOException {
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.getDecoder().decode(base64Token);
} catch (IllegalArgumentException var7) {
throw new BadCredentialsException("Failed to decode basic authentication token");
}
String token = new String(decoded, this.getCredentialsCharset(request));
int delim = token.indexOf(":");
if (delim == -1) {
throw new BadCredentialsException("Invalid basic authentication token");
} else {
return new String[]{token.substring(0, delim), token.substring(delim + 1)};
}
}