2017-08-17 35 views
8

我正在使用Spring Security對我的REST API進行身份驗證。身份驗證工作正常,Spring Security會返回一個帶有Set-Cookie的令牌。 rememberMe功能處於打開狀態,cookie中返回相同內容。Spring安全認證使用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

你試試這個:Vue.http.options.xhr = {withCredentials:真正} – Maddy

+1

是我沒有嘗試 – Sam

+2

您可以添加完整的HTTP請求和響應?也就是說,包含相應請求和響應的URL。 – Newbie

回答

4

在仔細查看您的響應/請求流程後,您將發起從端口8080到端口9000的請求,從而觸發同源策略(CORS)規則。默認情況下,CORS請求不會發送憑證/ cookie,如下面的鏈接所述。要啓用證書/ Cookie傳播,您需要在AJAX調用中設置「withCredentials」標誌。

此外,它看起來像你使用vuejs。要啓用憑證,您需要使用下面的設置。

Vue.http.options.credentials = true; 

MDN - Request with credentials

+1

我添加了'Vue.http.options.xhr = {withCredentials:true}'我仍然從服務器接收401 – Sam

+1

@Sam您可以在使用withCredentials時添加請求負載。 – Newbie

+1

更新了回覆和請求。請檢查 – Sam