首页 > 解决方案 > Spring Security - 为所有 URL 发送基本身份验证标头,而不仅仅是为安全端点发送

问题描述

在 Spring Security/Boot 应用程序中,我为特定的 URL 模式配置了基本身份验证:

http.antMatcher(StringUtils.join("myURL", "/**")).authorizeRequests().anyRequest().authenticated().and().httpBasic().realmName("realmName");

这就像一个魅力,当我请求该模式的 URL 时,浏览器会提示我提供凭据,然后我可以访问该端点。但是,在成功授权此端点后,浏览器会发送带有“Basic ...”令牌的 Authorization 标头,即使对于与上述代码中配置的 URL 无关的请求也是如此。例如网站主页。

这会导致 webapp 的其他授权机制(即 keycloak)被触发,因为它们期望 Authorization 标头中包含有效的令牌。我知道我可以配置 keycloak,它不会尝试解释以“Basic”开头的 Authorization-Header,但似乎这种困境的根本原因是 Header get 是为不发送的请求发送的属于基本身份验证 URL。

有什么方法可以告诉 Spring Security / 浏览器 / 仅当请求是针对与配置 http-basic 的模式匹配的 URL 时,basic-auth Authorization 标头才应包含在请求中?这不应该是标准行为吗?

示例网址:

标签: spring-securitybasic-authentication

解决方案


您的应用程序必须使用不同的包含目录和不同的领域,请参阅RFC 2617

2 基本认证方案

[...]
客户端应该假设所有在请求 URI 的路径字段中的最后一个符号元素的深度或更深的路径也都在当前挑战的基本领域值指定的保护空间内。客户端可以抢先发送相应的授权标头以及对该空间中资源的请求,而无需收到来自服务器的另一个挑战。

另请参阅铬源

// Helper to find the containing directory of path. In RFC 2617 this is what
// they call the "last symbolic element in the absolute path".
// Examples:
//   "/foo/bar.txt" --> "/foo/"
//   "/foo/" --> "/foo/"

在您的情况下,包含目录/用于您的一个应用程序。另一个应用程序位于包含目录的子路径中。因此,您的浏览器会抢先向Authorization两个应用程序发送相同的标头。


推荐阅读