@@ -32,26 +32,17 @@ JavaScript:
3232
3333.index.html
3434----
35- angular
36- .module("app", [])
37- ...
38- .controller("home", function($http, $location) {
39- var self = this;
40- ...
41- self.logout = function() {
42- $http.post('/logout', {}).success(function() {
43- self.authenticated = false;
44- $location.path("/");
45- }).error(function(data) {
46- console.log("Logout failed")
47- self.authenticated = false;
48- });
49- };
50- });
35+ var logout = function() {
36+ $.post("/logout", function() {
37+ $("#user").html('');
38+ $(".unauthenticated").show();
39+ $(".authenticated").hide();
40+ })
41+ return true;
42+ }
5143----
5244
53- The `logout()` function does a POST to `/logout` and then clears the
54- `authenticated` flag. Now we can switch over to the server side to
45+ The `logout()` function does a POST to `/logout` and then clears the dynamic content. Now we can switch over to the server side to
5546implement that endpoint.
5647
5748== Adding a Logout Endpoint
@@ -78,14 +69,17 @@ requires a token to be included in the request. The value of the token
7869is linked to the current session, which is what provides the
7970protection, so we need a way to get that data into our JavaScript app.
8071
81- AngularJS also has built in support for CSRF (they call it XSRF), but
82- it is implemented in a slightly different way than the out-of-the box
83- behaviour of Spring Security. What Angular would like is for the
84- server to send it a cookie called "XSRF-TOKEN" and if it sees that, it
85- will send the value back as a header named "X-XSRF-TOKEN". To teach
86- Spring Security about this we need to add a filter that creates the
87- cookie and also we need to tell the existing CRSF filter about the
88- header name. In the `WebSecurityConfigurer`:
72+ Many JavaScript frameworks have built in support for CSRF (e.g. in
73+ Angular they call it XSRF), but it is often implemented in a slightly
74+ different way than the out-of-the box behaviour of Spring
75+ Security. For instance in Angular the front end would like the server
76+ to send it a cookie called "XSRF-TOKEN" and if it sees that, it will
77+ send the value back as a header named "X-XSRF-TOKEN". We can implement
78+ the same behaviour with our simple jQuery client, and then the server
79+ side changes will work with other front end implementations with no or
80+ very few changes. To teach Spring Security about this we need to add a
81+ filter that creates the cookie and also we need to tell the existing
82+ CRSF filter about the header name. In the `WebSecurityConfigurer`:
8983
9084.SocialApplication.java
9185[source,java]
@@ -98,6 +92,44 @@ protected void configure(HttpSecurity http) throws Exception {
9892}
9993----
10094
95+ == Adding the CSRF Token in the Client
96+
97+ Since we are not using a higher level framework in this sample, we
98+ need to explicitly add the CSRF token, which is available as a cookie. The code is simple, if a bit long winded:
99+
100+ .index.html
101+ ----
102+ $.ajaxSetup({
103+ beforeSend : function(xhr, settings) {
104+ if (settings.type == 'POST' || settings.type == 'PUT'
105+ || settings.type == 'DELETE') {
106+ function getCookie(name) {
107+ var cookieValue = null;
108+ if (document.cookie && document.cookie != '') {
109+ var cookies = document.cookie.split(';');
110+ for (var i = 0; i < cookies.length; i++) {
111+ var cookie = jQuery.trim(cookies[i]);
112+ // Does this cookie string begin with the name we want?
113+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
114+ cookieValue = decodeURIComponent(cookie
115+ .substring(name.length + 1));
116+ break;
117+ }
118+ }
119+ }
120+ return cookieValue;
121+ }
122+ if (!(/^http:.*/.test(settings.url) || /^https:.*/
123+ .test(settings.url))) {
124+ // Only send the token to relative URLs i.e. locally.
125+ xhr.setRequestHeader("X-XSRF-TOKEN",
126+ getCookie('XSRF-TOKEN'));
127+ }
128+ }
129+ }
130+ });
131+ ----
132+
101133== Ready To Roll!
102134
103135With those changes in place we are ready to run the app and try out
0 commit comments