首页 文章

Spring Security身份验证跨域使用Cookie与Authorization标头

提问于
浏览
8

我使用Spring Security来验证我的REST API . 身份验证工作正常,Spring Security返回带有 Set-Cookie 的令牌 . rememberMe 功能已打开,并在cookie中返回相同的功能 .

当我发出后续请求时,除非我在 Authorization 标头中发送用户名/密码,否则身份验证将失败,而当我在邮递员中测试时,它会起作用 . 我看到它在请求中的cookie中添加了 JSESSIONID .

由于cookie为 Http-Only cookie,我认为我不能在我的JavaScript函数中读取它们 .

那么我该如何验证用户?我假设如果服务器返回带有 set-cookie 的cookie,浏览器应该自动为每个请求附加它 .

登录客户端请求:

context.$http.get(url, {
    headers:
    {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE',
      'Authorization': auth
    }
  }

请求标头:

Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en;q=0.8,fr;q=0.6,en-US;q=0.4
Access-Control-Request-Headers:access-control-allow-methods,access-control-allow-origin,authorization
Access-Control-Request-Method:GET
Connection:keep-alive
DNT:1
Host:localhost:9000
Origin:http://localhost:8080
Referer:http://localhost:8080/login?redirect=%2F
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

响应标头:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:8080
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:13
Content-Type:application/json;charset=UTF-8
Date:Fri, 18 Aug 2017 05:40:55 GMT
Expires:0
Pragma:no-cache
Set-Cookie:remember-me=dTVTMi94dnVkQzJtYXRFYmJkR1VKZz09OjA1T1F4RXVOV0RiTEx4VFdUSVByeGc9PQ; Max-Age=86400; Expires=Sat, 19-Aug-2017 05:40:55 GMT; Path=/; Secure; HttpOnly
Set-Cookie:JSESSIONID=4A856E0216191E8601100B600E4A227B; Path=/; HttpOnly
Vary:Origin
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

后续获取数据的请求:

this.$http.get(url).then(function (res) {
          this.items = res.data
        })

客户要求:

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en;q=0.8,fr;q=0.6,en-US;q=0.4
Connection:keep-alive
DNT:1
Host:localhost:9000
Origin:http://localhost:8080
Referer:http://localhost:8080/Languages
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

服务器响应:

HTTP/1.1 401
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
Access-Control-Allow-Origin: http://localhost:8080
Vary: Origin
Access-Control-Allow-Credentials: true
WWW-Authenticate: Basic realm="Realm"
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 18 Aug 2017 05:43:26 GMT

{timestamp: 1503038407254, status: 401, error: "Unauthorized",…}
error :
"Unauthorized"
message:"Full authentication is required to access this resource"
path:"/languages"
status:401
timestamp:1503038407254

添加 withCredentials : true

GET /languages HTTP/1.1
Host: 192.168.16.142:12345
Connection: keep-alive
Access-Control-Allow-Origin: *
Accept: application/json, text/plain, */*
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Access-Control-Allow-Methods: GET,PUT,POST,DELETE
DNT: 1
Referer: http://localhost:8080/languages
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.8,fr;q=0.6,en-US;q=0.4

响应:

Access-Control-Allow-Origin:*
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Type:application/json;charset=UTF-8
Date:Mon, 21 Aug 2017 06:26:24 GMT
Expires:0
Pragma:no-cache
Transfer-Encoding:chunked
Vary:Origin
WWW-Authenticate:Basic realm="Realm"
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

仅供参考:我在前端使用vuejs .

1 回答

  • 6

    仔细查看您的响应/请求流后,您将发出从端口8080到端口9000的请求,这些请求会触发同源策略(CORS)规则 . 默认情况下,CORS请求不会发送凭据/ cookie,如下面的链接所示 . 要启用凭据/ cookie传播,您需要在AJAX调用中设置“withCredentials”标志 .

    而且,看起来你正在使用vuejs . 要启用withcredentials,您需要使用以下设置 .

    Vue.http.options.credentials = true;
    

    MDN - Request with credentials

相关问题