Reputation: 4973
The goal is to call a remote login-service with HTTP Basic and receive the JSESSIONID
for further usage.
So far I achieved the service call including a 200
response. My tests with restassured work smoothly and indicates that the JSESSIONID
is properly provided by the login-service. The spring backend service is annotated with @CrossOrigin
.
// assure we are not logged in
RestAssured.baseURI = "https://" + ip;
RestAssured.basePath = "/user";
Response responseA = post("/create"); // /user/create is a secured service
assertEquals(401, responseA.statusCode());
// log in and save the token
RestAssured.baseURI = "https://" + username + ":pass@" + ip; // http basic auth is used
RestAssured.basePath = "/user";
Response responseB = post("/login");
assertEquals(200, responseB.statusCode());
String jsessionId = responseB.getCookie("JSESSIONID");
// C50C28EA1F3ABBB76F0E4189A772A4E9
RestAssured.baseURI = "https://" + ip;
RestAssured.basePath = "/user";
// call a service without token or credentials --> 401
Response responseC = get("/id"); // /user/id is a secured service
assertEquals(401, responseC.statusCode());
// call a service with the token
RestAssured.sessionId = jsessionId;
Response responseD = get("/id");
assertEquals(200, responseD.statusCode());
The test is green.
In our Angular2 frontend app we have a login page, whose submit button runs the following code through the onSubmit()
method.
_url = "theLoginServiceUrl"
createAuthorizationHeader(username: string, password: string, headers:Headers) {
headers.append('Authorization', 'Basic ' + btoa(username + ':' + password));
// tried all of these, but they didn't fix the problem
// headers.append('Access-Control-Allow-Origin', '*');
// headers.append('Access-Control-Allow-Headers', '*');
// headers.append('Access-Control-Allow-Methods', '*');
}
login (username: string, password: string) {
let headers = new Headers();
this.createAuthorizationHeader(username, password, headers);
return this._http.post(this._url, "", {
headers: headers
});
}
onSubmit() {
this.login(this.currentUser.username, this.currentUser.password)
.subscribe((res) => {
var headers = res.headers;
console.log(headers);
// Headers {_headersMap: Map}
// <entries>[3]
// {"Pragma" => Array[1]}
// {"Cache-Control" => Array[1]}
// {"Expires" => Array[1]}
var setCookieHeader = headers.get('Set-Cookie');
console.log(setCookieHeader)
// null
}
);
}
As you see from the comments I am not able to access Set-Cookie
header. In the browser however I see the successful calls including the Set-Cookie
header:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
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
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=58A072F2BB40A711CB42233CA4EB7BF6; Path=/; Secure; HttpOnly
Access-Control-Allow-Origin: http://localhost:3000
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Length: 0
Date: Fri, 06 May 2016 10:43:21 GMT
Note that this all runs through HTTPS
.
Frontend details:
"typescript": "^1.7.5"
"angular2": "2.0.0-beta.7"
Why can't I access the Set-Cookie
within my Angular2 code? What do I have to change?
Upvotes: 3
Views: 3371
Reputation: 657476
When Secure
is set for a cookie, then you can't read it using JavaScript. The purpose of the cookie is only to authenticate made requests and will be sent by the browser which each request but for security concerns it is not available to JavaScript code.
For JS code to check if the user is logged in use different measures like a call to the server that responds with the current logged-in state.
See also How to read a secure cookie using JavaScript
Upvotes: 2