【发布时间】:2019-07-05 11:50:49
【问题描述】:
我正在发送一个基本身份验证的 GET 请求,服务器(后端 API)将返回(如果身份验证成功)一个 cookie。这对 POSTMAN 来说工作正常,但在浏览器中没有设置 cookie。
@GetMapping("/login")
@ResponseStatus(value=HttpStatus.OK)
public void loginUser( final HttpServletRequest request ,final HttpServletResponse response) throws UnsupportedEncodingException {
setAuthCookieToResonse(request,response);
}
private void setAuthCookieToResonse(final HttpServletRequest request ,final HttpServletResponse response) throws UnsupportedEncodingException {
logger.debug("Adding cookie after authentication");
String cookieKey = "auth";
String cookieValue = request.getHeader("Authorization");
if (cookieValue != null) {
Cookie cookie = new Cookie(cookieKey, URLEncoder.encode(cookieValue, "utf-8"));
cookie.setHttpOnly(true);
cookie.setDomain("localhost");
response.addCookie(cookie);
}
}
这是我的申请流程:
- 使用基本身份验证的浏览器/POSTMAN 登录。发送凭据
使用
Authorization Basic xxxxxx==标头。 - 服务器读取身份验证详细信息,如果正确,它会创建一个
名为
auth的 cookie 并将其与响应(以上代码)一起发回。 对于安全层,我使用的是 Spring 安全性。 - 对于进一步的请求,该 cookie 将自动发送
每个请求。现在我不得不拿走那个饼干并提取
身份验证详细信息。在那之后,我不得不添加
Authorization Basic xxxxxx==到那个请求(因为现在Authorization不是客户端发送的,只发送了cookie)。为了这 我创建了Filter,它将在 Spring 之前运行BasicAuthenticationFilter.class
第 2 步适用于 POSTMAN,但不适用于浏览器。在 POSTMAN 中,服务器发送的response 包含Set-Cookie →auth=Basic xxxxxxxx=; Domain=localhost; HttpOnly。
curl -i -u pu@gmail.com:password@ http://localhost:8085/api/v1/login
HTTP/1.1 200
Set-Cookie: auth=Basic xxxxxxxx==; HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Tue, 12 Feb 2019 05:59:33 GMT
浏览器中的响应头:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3007
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Tue, 12 Feb 2019 11:52:10 GMT
Expires: 0
Pragma: no-cache
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
这里我需要做哪些额外的配置?
【问题讨论】:
-
浏览器在服务器请求之前不会发送
Authorization标头。使用 POSTMAN,您可能已经告诉它先发制人地 发送标头,即服务器不请自来,所以这就是它在那里工作的原因。浏览器从服务器接收到带有WWW-Authenticate标头的401 Unauthorized后,将在第二个请求中发送Authorization标头。您的服务器是否配置为这样做? -
@Andreas 我已经添加了应用程序流程。如果还需要什么,请告诉我。
-
您能否在浏览器中添加原始 http 响应?
-
@Ilya 已更新。请看一看。
-
看来你没有理解我的评论。浏览器不会发送
Authorization标头,除非服务器 提示。查看浏览器请求中的标头,看看它是否真的发送了Authorization标头。 --- 另外,当使用 BASIC 身份验证时,通常没有明确的/logonURL,因为任何 webapp URL 都可以进行登录。正常流程是:1)浏览器发送GET到/foo。 2) 服务器发送401 Unauthorized。 3) 浏览器提示用户输入密码。 4) 浏览器将 GET 重新发送到/foo并带有 Auth 标头。 5)服务器验证密码并处理/foo请求。
标签: java spring-boot cookies