Step 1.
Step 2. Start the application in debug mode.
Step 3. Ensure tomcat is started.
Step 4. Start firefox in private browsing.
Step 5. Activate firebug.
Step 6. Type the address http://localhost:8080
Step 7. Enter user as user and password as password and click ok.
Step 8. It will prompt back the eclipse debug window.
Step 9. Do not click play.
Step 10. Take a note of the request calls.
Step 11. Take a note of the following request call in detail. Note down the authorization header.
Step 12. Below are the request and response headers in detail.
Step 14. You will get javascript pop up on the screen.
Step 15. Click OK.
Step 16. Make a note of the request and response headers.
17. How does it work?
Step 3. Ensure tomcat is started.
Step 4. Start firefox in private browsing.
Step 5. Activate firebug.
Step 6. Type the address http://localhost:8080
Step 7. Enter user as user and password as password and click ok.
Step 8. It will prompt back the eclipse debug window.
Step 9. Do not click play.
Step 10. Take a note of the request calls.
Step 11. Take a note of the following request call in detail. Note down the authorization header.
Step 12. Below are the request and response headers in detail.
1. Request - http://localhost:8080/
GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
If-Modified-Since: Mon, 16 Mar 2015 00:09:18 GMT
Copy as curl from firebug.
curl 'http://localhost:8080/' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.5' -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Host: localhost:8080' -H 'If-Modified-Since: Mon, 16 Mar 2015 00:09:18 GMT' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0'
2. Response
HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Date: Mon, 16 Mar 2015 01:22:55 GMT
3. Request-http://localhost:8080/css/angular-bootstrap.css
GET /css/angular-bootstrap.css HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: text/css,*/*;q=0.1
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://localhost:8080/
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
If-Modified-Since: Mon, 16 Mar 2015 00:09:41 GMT
curl 'http://localhost:8080/css/angular-bootstrap.css' -H 'Accept: text/css,*/*;q=0.1' -H 'Accept- Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.5' -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Host: localhost:8080' -H 'If- Modified-Since: Mon, 16 Mar 2015 00:09:41 GMT' -H 'Referer: http://localhost:8080/' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0'
4. Response
HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Date: Mon, 16 Mar 2015 01:22:55 GMT
5. Request-http://localhost:8080/js/angular-bootstrap.js
Accept-Encoding: gzip, deflate
DNT: 1
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
If-Modified-Since: Mon, 16 Mar 2015 00:09:18 GMT
Copy as curl from firebug.
curl 'http://localhost:8080/' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.5' -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Host: localhost:8080' -H 'If-Modified-Since: Mon, 16 Mar 2015 00:09:18 GMT' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0'
2. Response
HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Date: Mon, 16 Mar 2015 01:22:55 GMT
3. Request-http://localhost:8080/css/angular-bootstrap.css
GET /css/angular-bootstrap.css HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: text/css,*/*;q=0.1
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://localhost:8080/
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
If-Modified-Since: Mon, 16 Mar 2015 00:09:41 GMT
curl 'http://localhost:8080/css/angular-bootstrap.css' -H 'Accept: text/css,*/*;q=0.1' -H 'Accept- Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.5' -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Host: localhost:8080' -H 'If- Modified-Since: Mon, 16 Mar 2015 00:09:41 GMT' -H 'Referer: http://localhost:8080/' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0'
4. Response
HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Date: Mon, 16 Mar 2015 01:22:55 GMT
5. Request-http://localhost:8080/js/angular-bootstrap.js
GET /js/angular-bootstrap.js HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://localhost:8080/
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
If-Modified-Since: Mon, 16 Mar 2015 00:09:41 GMT
curl 'http://localhost:8080/js/angular-bootstrap.js' -H 'Host: localhost:8080' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0' -H 'Accept: */*' -H 'Accept- Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'DNT: 1' -H 'Referer: http://localhost:8080/' -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Connection: keep- alive' -H 'If-Modified-Since: Mon, 16 Mar 2015 00:09:41 GMT'
6. Response
HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Date: Mon, 16 Mar 2015 01:22:55 GMT
7. Request-http://localhost:8080/js/hello.js
GET /js/hello.js HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://localhost:8080/
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
If-Modified-Since: Mon, 16 Mar 2015 00:09:18 GMT
curl 'http://localhost:8080/js/hello.js' -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Accept- Language: en-US,en;q=0.5' -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Host: localhost:8080' -H 'If-Modified-Since: Mon, 16 Mar 2015 00:09:18 GMT' -H 'Referer: http://localhost:8080/' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0'
8. Response
HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Date: Mon, 16 Mar 2015 01:22:55 GMT
Step 13. Click play on the eclipse debug.
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://localhost:8080/
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
If-Modified-Since: Mon, 16 Mar 2015 00:09:41 GMT
curl 'http://localhost:8080/js/angular-bootstrap.js' -H 'Host: localhost:8080' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0' -H 'Accept: */*' -H 'Accept- Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'DNT: 1' -H 'Referer: http://localhost:8080/' -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Connection: keep- alive' -H 'If-Modified-Since: Mon, 16 Mar 2015 00:09:41 GMT'
6. Response
HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Date: Mon, 16 Mar 2015 01:22:55 GMT
7. Request-http://localhost:8080/js/hello.js
GET /js/hello.js HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://localhost:8080/
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
If-Modified-Since: Mon, 16 Mar 2015 00:09:18 GMT
curl 'http://localhost:8080/js/hello.js' -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Accept- Language: en-US,en;q=0.5' -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Host: localhost:8080' -H 'If-Modified-Since: Mon, 16 Mar 2015 00:09:18 GMT' -H 'Referer: http://localhost:8080/' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0'
8. Response
HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Date: Mon, 16 Mar 2015 01:22:55 GMT
Step 13. Click play on the eclipse debug.
Step 15. Click OK.
Step 16. Make a note of the request and response headers.
17. How does it work?
http://spring.io/blog/2015/01/12/spring-and-angular-js-a-secure-single-page-application#add-a-home-
page
The interactions between the browser and the backend can be seen in your browser if you use some
The interactions between the browser and the backend can be seen in your browser if you use some
developer tools (usually F12 opens this up,
works in Chrome by default, requires a plugin in Firefox).
Here’s a summary:
Verb Path Status Response
GET / 401 Browser prompts for authentication
GET / 200 index.html
GET /css/angular-bootstrap.css 200 Twitter bootstrap CSS
GET /js/angular-bootsrap.cs 200 Bootstrap and Angular JS
GET /js/hello.js 200 Application logic
GET /resource 200 JSON greeting
Here’s a summary:
Verb Path Status Response
GET / 401 Browser prompts for authentication
GET / 200 index.html
GET /css/angular-bootstrap.css 200 Twitter bootstrap CSS
GET /js/angular-bootsrap.cs 200 Bootstrap and Angular JS
GET /js/hello.js 200 Application logic
GET /resource 200 JSON greeting
You might not see the 401 because the browser treats the home page load as a single transaction and
you might see 2 requests for “/resource” because there is a CORS negotiation.
you might see 2 requests for “/resource” because there is a CORS negotiation.
Look more closely at the requests and you will see that all of them have an “Authorization” header,
something like this:
18. CORS
Cross-origin resource sharing (CORS) is a mechanism that allows many resources (e.g. fonts, JavaScript, etc.) on a web page to be requested from another domain outside the domain from which the resource originated.[1]
A web page may freely embed images, stylesheets, scripts, iframes, videos and some plugin content (such as Adobe Flash) from any other domain. However embedded web fonts and AJAX (XMLHttpRequest) requests have traditionally been limited to accessing the same domain as the parent web page (as per the same-origin security policy). "Cross-domain" AJAX requests are forbidden by default because of their ability to perform advanced requests (POST, PUT, DELETE and other types of HTTP requests, along with specifying custom HTTP headers) that introduce many security issues as described in cross-site scripting.
CORS defines a way in which a browser and server can interact to safely determine whether or not to allow the cross-origin request.[2] It allows for more freedom and functionality than purely same-origin requests, but is more secure than simply allowing all cross-origin requests. It is a recommended standard of the W3C
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
19. Issues As is.
What’s Wrong with That?
On the face of it, it seems like we did a pretty good job, it’s concise, easy to implement, all our data are secured by a secret password, and it would still work if we changed the front end or backend technologies. But there are some issues.
Authorization: Basic dXNlcjpwYXNzd29yZA==
The browser is sending the username and password with every request (so remember to use HTTPS
exclusively in production). There’s nothing “Angular” about that, so it works with your JavaScript
framework or non-framework of choice. 18. CORS
Cross-origin resource sharing (CORS) is a mechanism that allows many resources (e.g. fonts, JavaScript, etc.) on a web page to be requested from another domain outside the domain from which the resource originated.[1]
A web page may freely embed images, stylesheets, scripts, iframes, videos and some plugin content (such as Adobe Flash) from any other domain. However embedded web fonts and AJAX (XMLHttpRequest) requests have traditionally been limited to accessing the same domain as the parent web page (as per the same-origin security policy). "Cross-domain" AJAX requests are forbidden by default because of their ability to perform advanced requests (POST, PUT, DELETE and other types of HTTP requests, along with specifying custom HTTP headers) that introduce many security issues as described in cross-site scripting.
CORS defines a way in which a browser and server can interact to safely determine whether or not to allow the cross-origin request.[2] It allows for more freedom and functionality than purely same-origin requests, but is more secure than simply allowing all cross-origin requests. It is a recommended standard of the W3C
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
19. Issues As is.
What’s Wrong with That?
On the face of it, it seems like we did a pretty good job, it’s concise, easy to implement, all our data are secured by a secret password, and it would still work if we changed the front end or backend technologies. But there are some issues.
-
Basic authentication is restricted to username and password authentication.
-
The authentication UI is ubiquitous but ugly (browser dialog).
• There is no protection from Cross Site Request Forgery (CSRF).
CSRF isn’t really an issue with our application as it stands since it only needs to GET the backend resources (i.e. no state is changed in the server). As soon as you have a POST, PUT or DELETE in your application it simply isn’t secure any more by any reasonable modern measure.
In the next article in this series we will extend the application to use form-based authentication, which is a lot more flexible than HTTP Basic. Once we have a form we will need CSRF protection, and both Spring Security and Angular have some nice out-of-the box features to help with this. Spoiler: we are going to need to use the HttpSession.
No comments:
Post a Comment