Spring Boot and Security with custom AngularJS Login page











up vote
15
down vote

favorite
3












I'm implementing a custom AngularJS login page for Spring Security, and I'm having issues authenticating.



I'm following this tutorial/example, and their example works fine locally: https://github.com/dsyer/spring-security-angular/tree/master/single



However, when I try to implement this myself, I'm not able to authenticate, and I'm not sure where my mistake is.



A POST is made to /login with credentials, (the curl is identical to the example), and I receive a 302 Found with a redirect to GET /login/, which returns a 404 Not Found.



When I try to POST to /login, the Spring does not generate any debug logs, so I'm not sure how it is serving the 302.



My code can be found here: https://github.com/AndrewBell/spring-angular-starter/tree/master



Notable changes (And most likely the source of my issues):




  • File structure changes


  • Using strictly Angular (No jQuery) - Which results in a different function needed to make the POST request


  • Using bower instead of wro4j


  • Angular code styling/scoping



Many related Spring Security questions suggest the POST request is formatted incorrectly, but mine appears to be the same as the example (at least when I copy to curl in chrome dev console). Others suggest implementing custom authorization providers, but it is not needed in the example, so I'm perplexed to what the difference is between mine and the example. Help me Stack Exchange, you're my only hope.



Dev Tools: imgurDOTcom/a/B2KmV



Relevant code:



login.js






'use strict';
angular
.module('webApp')
.controller('LoginCtrl', ['$root`enter code here`Scope', '$scope', '$http', '$location', '$route', function($rootScope, $scope, $http, $location, $route) {
console.log("LoginCtrl created.");

var vm = this;
vm.credentials = {
username: "",
password: ""
};
//vm.login = login;

$scope.tab = function(route) {
return $route.current && route === $route.current.controller;
};

var authenticate = function(callback) {

$http.get('user').success(function(data) {
console.log("/user success: " + JSON.stringify(data));
if (data.name) {
console.log("And Authenticated!");
$rootScope.authenticated = true;
} else {
console.log("But received invalid data.");
$rootScope.authenticated = false;
}
callback && callback();
}).error(function(response) {
console.log("/user failure." + JSON.stringify(response));
$rootScope.authenticated = false;
callback && callback();
});

};

authenticate();

$scope.login = function() {

var data2 = 'username=' + encodeURIComponent(vm.credentials.username) +
'&password=' + encodeURIComponent(vm.credentials.password);

$http.post('login', data2, {
headers : {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function() {
authenticate(function() {
if ($rootScope.authenticated) {
console.log("Login succeeded");
$location.path("/");
$scope.error = false;
$rootScope.authenticated = true;
} else {
console.log("Login failed with redirect");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
}
});
}).error(function() {
console.log("Login failed");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
})
};

$scope.logout = function() {
$http.post('logout', {}).success(function() {
$rootScope.authenticated = false;
$location.path("/");
}).error(function() {
console.log("Logout failed");
$rootScope.authenticated = false;
});
}

}]);





application.java



package com.recursivechaos.springangularstarter;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@SpringBootApplication
@RestController
public class Application {

public static void main(String args) {
SpringApplication.run(Application.class, args);
}

@RequestMapping("/user")
public Principal user(Principal user) {
return user;
}

@RequestMapping("/resource")
public Map<String, Object> home() {
Map<String, Object> model = new HashMap<>();
model.put("id", UUID.randomUUID().toString());
model.put("content", "Hello World");
return model;
}

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
formLogin().
//loginPage("/#/login").
and().
logout().
and().
authorizeRequests().
antMatchers("/index.html", "/home/**", "/login/**", "/bower_components/**", "/", "/main.js", "/login/", "/navigation/**","/login","login/","/login.html").
permitAll().
anyRequest().
authenticated().
and().
csrf().
csrfTokenRepository(csrfTokenRepository()).
and().
addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}

private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}

private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}

}









share|improve this question






















  • If you get redirected to /login that means you are not authenticated (but it shouldn't be a 404 so that's odd). You can switch on debug logging for org.springframework.security to get more detailed information about the access decision (I expect the credentials were bad in some way), e.g. set logging.level.org.springframework.security=DEBUG in application.[properties,yml].
    – Dave Syer
    Feb 11 '15 at 18:06












  • @DaveSyer Looking through the logs, I can't seem to even see a POST to /login How can I verify that Spring is handling POST /login? pastebin.com/GeUkCUvg
    – Andrew
    Feb 11 '15 at 20:12








  • 1




    It appears to be a path issue (or possibly scope), as I was able to pull your "single" project from the github examples, remove the wro4j, and replace with the following bower dependencies: "angular": "^1.3.0", "angular-resource": "^1.3.0", "angular-bootstrap": "~0.12.0", "bootstrap-css-only": "~3.3.2", "angular-route": "~1.3.11" And using... var req = 'username=' + ($scope.credentials.username) + =' + ($scope.credentials.password); $http.post('login', req.... Seems to work fine
    – Andrew
    Feb 11 '15 at 21:00












  • I also can't see a POST to /login but the log seemed to end in the middle of loading the homepage. Are you sure your client actually sent a POST anyway (can you see that in the client, and what are the request/response headers)?
    – Dave Syer
    Feb 11 '15 at 22:14










  • OK, the 404 is obvious: your client is sending a GET to /login/ which you have declared to be permitAll() but haven't provided a view for. Spring Security provides a whitelabel view at /login (no trailing slash), and it only sends /login in 302 responses, so your client is behaving rather strangely.
    – Dave Syer
    Feb 12 '15 at 10:15















up vote
15
down vote

favorite
3












I'm implementing a custom AngularJS login page for Spring Security, and I'm having issues authenticating.



I'm following this tutorial/example, and their example works fine locally: https://github.com/dsyer/spring-security-angular/tree/master/single



However, when I try to implement this myself, I'm not able to authenticate, and I'm not sure where my mistake is.



A POST is made to /login with credentials, (the curl is identical to the example), and I receive a 302 Found with a redirect to GET /login/, which returns a 404 Not Found.



When I try to POST to /login, the Spring does not generate any debug logs, so I'm not sure how it is serving the 302.



My code can be found here: https://github.com/AndrewBell/spring-angular-starter/tree/master



Notable changes (And most likely the source of my issues):




  • File structure changes


  • Using strictly Angular (No jQuery) - Which results in a different function needed to make the POST request


  • Using bower instead of wro4j


  • Angular code styling/scoping



Many related Spring Security questions suggest the POST request is formatted incorrectly, but mine appears to be the same as the example (at least when I copy to curl in chrome dev console). Others suggest implementing custom authorization providers, but it is not needed in the example, so I'm perplexed to what the difference is between mine and the example. Help me Stack Exchange, you're my only hope.



Dev Tools: imgurDOTcom/a/B2KmV



Relevant code:



login.js






'use strict';
angular
.module('webApp')
.controller('LoginCtrl', ['$root`enter code here`Scope', '$scope', '$http', '$location', '$route', function($rootScope, $scope, $http, $location, $route) {
console.log("LoginCtrl created.");

var vm = this;
vm.credentials = {
username: "",
password: ""
};
//vm.login = login;

$scope.tab = function(route) {
return $route.current && route === $route.current.controller;
};

var authenticate = function(callback) {

$http.get('user').success(function(data) {
console.log("/user success: " + JSON.stringify(data));
if (data.name) {
console.log("And Authenticated!");
$rootScope.authenticated = true;
} else {
console.log("But received invalid data.");
$rootScope.authenticated = false;
}
callback && callback();
}).error(function(response) {
console.log("/user failure." + JSON.stringify(response));
$rootScope.authenticated = false;
callback && callback();
});

};

authenticate();

$scope.login = function() {

var data2 = 'username=' + encodeURIComponent(vm.credentials.username) +
'&password=' + encodeURIComponent(vm.credentials.password);

$http.post('login', data2, {
headers : {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function() {
authenticate(function() {
if ($rootScope.authenticated) {
console.log("Login succeeded");
$location.path("/");
$scope.error = false;
$rootScope.authenticated = true;
} else {
console.log("Login failed with redirect");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
}
});
}).error(function() {
console.log("Login failed");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
})
};

$scope.logout = function() {
$http.post('logout', {}).success(function() {
$rootScope.authenticated = false;
$location.path("/");
}).error(function() {
console.log("Logout failed");
$rootScope.authenticated = false;
});
}

}]);





application.java



package com.recursivechaos.springangularstarter;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@SpringBootApplication
@RestController
public class Application {

public static void main(String args) {
SpringApplication.run(Application.class, args);
}

@RequestMapping("/user")
public Principal user(Principal user) {
return user;
}

@RequestMapping("/resource")
public Map<String, Object> home() {
Map<String, Object> model = new HashMap<>();
model.put("id", UUID.randomUUID().toString());
model.put("content", "Hello World");
return model;
}

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
formLogin().
//loginPage("/#/login").
and().
logout().
and().
authorizeRequests().
antMatchers("/index.html", "/home/**", "/login/**", "/bower_components/**", "/", "/main.js", "/login/", "/navigation/**","/login","login/","/login.html").
permitAll().
anyRequest().
authenticated().
and().
csrf().
csrfTokenRepository(csrfTokenRepository()).
and().
addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}

private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}

private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}

}









share|improve this question






















  • If you get redirected to /login that means you are not authenticated (but it shouldn't be a 404 so that's odd). You can switch on debug logging for org.springframework.security to get more detailed information about the access decision (I expect the credentials were bad in some way), e.g. set logging.level.org.springframework.security=DEBUG in application.[properties,yml].
    – Dave Syer
    Feb 11 '15 at 18:06












  • @DaveSyer Looking through the logs, I can't seem to even see a POST to /login How can I verify that Spring is handling POST /login? pastebin.com/GeUkCUvg
    – Andrew
    Feb 11 '15 at 20:12








  • 1




    It appears to be a path issue (or possibly scope), as I was able to pull your "single" project from the github examples, remove the wro4j, and replace with the following bower dependencies: "angular": "^1.3.0", "angular-resource": "^1.3.0", "angular-bootstrap": "~0.12.0", "bootstrap-css-only": "~3.3.2", "angular-route": "~1.3.11" And using... var req = 'username=' + ($scope.credentials.username) + =' + ($scope.credentials.password); $http.post('login', req.... Seems to work fine
    – Andrew
    Feb 11 '15 at 21:00












  • I also can't see a POST to /login but the log seemed to end in the middle of loading the homepage. Are you sure your client actually sent a POST anyway (can you see that in the client, and what are the request/response headers)?
    – Dave Syer
    Feb 11 '15 at 22:14










  • OK, the 404 is obvious: your client is sending a GET to /login/ which you have declared to be permitAll() but haven't provided a view for. Spring Security provides a whitelabel view at /login (no trailing slash), and it only sends /login in 302 responses, so your client is behaving rather strangely.
    – Dave Syer
    Feb 12 '15 at 10:15













up vote
15
down vote

favorite
3









up vote
15
down vote

favorite
3






3





I'm implementing a custom AngularJS login page for Spring Security, and I'm having issues authenticating.



I'm following this tutorial/example, and their example works fine locally: https://github.com/dsyer/spring-security-angular/tree/master/single



However, when I try to implement this myself, I'm not able to authenticate, and I'm not sure where my mistake is.



A POST is made to /login with credentials, (the curl is identical to the example), and I receive a 302 Found with a redirect to GET /login/, which returns a 404 Not Found.



When I try to POST to /login, the Spring does not generate any debug logs, so I'm not sure how it is serving the 302.



My code can be found here: https://github.com/AndrewBell/spring-angular-starter/tree/master



Notable changes (And most likely the source of my issues):




  • File structure changes


  • Using strictly Angular (No jQuery) - Which results in a different function needed to make the POST request


  • Using bower instead of wro4j


  • Angular code styling/scoping



Many related Spring Security questions suggest the POST request is formatted incorrectly, but mine appears to be the same as the example (at least when I copy to curl in chrome dev console). Others suggest implementing custom authorization providers, but it is not needed in the example, so I'm perplexed to what the difference is between mine and the example. Help me Stack Exchange, you're my only hope.



Dev Tools: imgurDOTcom/a/B2KmV



Relevant code:



login.js






'use strict';
angular
.module('webApp')
.controller('LoginCtrl', ['$root`enter code here`Scope', '$scope', '$http', '$location', '$route', function($rootScope, $scope, $http, $location, $route) {
console.log("LoginCtrl created.");

var vm = this;
vm.credentials = {
username: "",
password: ""
};
//vm.login = login;

$scope.tab = function(route) {
return $route.current && route === $route.current.controller;
};

var authenticate = function(callback) {

$http.get('user').success(function(data) {
console.log("/user success: " + JSON.stringify(data));
if (data.name) {
console.log("And Authenticated!");
$rootScope.authenticated = true;
} else {
console.log("But received invalid data.");
$rootScope.authenticated = false;
}
callback && callback();
}).error(function(response) {
console.log("/user failure." + JSON.stringify(response));
$rootScope.authenticated = false;
callback && callback();
});

};

authenticate();

$scope.login = function() {

var data2 = 'username=' + encodeURIComponent(vm.credentials.username) +
'&password=' + encodeURIComponent(vm.credentials.password);

$http.post('login', data2, {
headers : {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function() {
authenticate(function() {
if ($rootScope.authenticated) {
console.log("Login succeeded");
$location.path("/");
$scope.error = false;
$rootScope.authenticated = true;
} else {
console.log("Login failed with redirect");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
}
});
}).error(function() {
console.log("Login failed");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
})
};

$scope.logout = function() {
$http.post('logout', {}).success(function() {
$rootScope.authenticated = false;
$location.path("/");
}).error(function() {
console.log("Logout failed");
$rootScope.authenticated = false;
});
}

}]);





application.java



package com.recursivechaos.springangularstarter;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@SpringBootApplication
@RestController
public class Application {

public static void main(String args) {
SpringApplication.run(Application.class, args);
}

@RequestMapping("/user")
public Principal user(Principal user) {
return user;
}

@RequestMapping("/resource")
public Map<String, Object> home() {
Map<String, Object> model = new HashMap<>();
model.put("id", UUID.randomUUID().toString());
model.put("content", "Hello World");
return model;
}

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
formLogin().
//loginPage("/#/login").
and().
logout().
and().
authorizeRequests().
antMatchers("/index.html", "/home/**", "/login/**", "/bower_components/**", "/", "/main.js", "/login/", "/navigation/**","/login","login/","/login.html").
permitAll().
anyRequest().
authenticated().
and().
csrf().
csrfTokenRepository(csrfTokenRepository()).
and().
addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}

private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}

private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}

}









share|improve this question













I'm implementing a custom AngularJS login page for Spring Security, and I'm having issues authenticating.



I'm following this tutorial/example, and their example works fine locally: https://github.com/dsyer/spring-security-angular/tree/master/single



However, when I try to implement this myself, I'm not able to authenticate, and I'm not sure where my mistake is.



A POST is made to /login with credentials, (the curl is identical to the example), and I receive a 302 Found with a redirect to GET /login/, which returns a 404 Not Found.



When I try to POST to /login, the Spring does not generate any debug logs, so I'm not sure how it is serving the 302.



My code can be found here: https://github.com/AndrewBell/spring-angular-starter/tree/master



Notable changes (And most likely the source of my issues):




  • File structure changes


  • Using strictly Angular (No jQuery) - Which results in a different function needed to make the POST request


  • Using bower instead of wro4j


  • Angular code styling/scoping



Many related Spring Security questions suggest the POST request is formatted incorrectly, but mine appears to be the same as the example (at least when I copy to curl in chrome dev console). Others suggest implementing custom authorization providers, but it is not needed in the example, so I'm perplexed to what the difference is between mine and the example. Help me Stack Exchange, you're my only hope.



Dev Tools: imgurDOTcom/a/B2KmV



Relevant code:



login.js






'use strict';
angular
.module('webApp')
.controller('LoginCtrl', ['$root`enter code here`Scope', '$scope', '$http', '$location', '$route', function($rootScope, $scope, $http, $location, $route) {
console.log("LoginCtrl created.");

var vm = this;
vm.credentials = {
username: "",
password: ""
};
//vm.login = login;

$scope.tab = function(route) {
return $route.current && route === $route.current.controller;
};

var authenticate = function(callback) {

$http.get('user').success(function(data) {
console.log("/user success: " + JSON.stringify(data));
if (data.name) {
console.log("And Authenticated!");
$rootScope.authenticated = true;
} else {
console.log("But received invalid data.");
$rootScope.authenticated = false;
}
callback && callback();
}).error(function(response) {
console.log("/user failure." + JSON.stringify(response));
$rootScope.authenticated = false;
callback && callback();
});

};

authenticate();

$scope.login = function() {

var data2 = 'username=' + encodeURIComponent(vm.credentials.username) +
'&password=' + encodeURIComponent(vm.credentials.password);

$http.post('login', data2, {
headers : {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function() {
authenticate(function() {
if ($rootScope.authenticated) {
console.log("Login succeeded");
$location.path("/");
$scope.error = false;
$rootScope.authenticated = true;
} else {
console.log("Login failed with redirect");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
}
});
}).error(function() {
console.log("Login failed");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
})
};

$scope.logout = function() {
$http.post('logout', {}).success(function() {
$rootScope.authenticated = false;
$location.path("/");
}).error(function() {
console.log("Logout failed");
$rootScope.authenticated = false;
});
}

}]);





application.java



package com.recursivechaos.springangularstarter;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@SpringBootApplication
@RestController
public class Application {

public static void main(String args) {
SpringApplication.run(Application.class, args);
}

@RequestMapping("/user")
public Principal user(Principal user) {
return user;
}

@RequestMapping("/resource")
public Map<String, Object> home() {
Map<String, Object> model = new HashMap<>();
model.put("id", UUID.randomUUID().toString());
model.put("content", "Hello World");
return model;
}

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
formLogin().
//loginPage("/#/login").
and().
logout().
and().
authorizeRequests().
antMatchers("/index.html", "/home/**", "/login/**", "/bower_components/**", "/", "/main.js", "/login/", "/navigation/**","/login","login/","/login.html").
permitAll().
anyRequest().
authenticated().
and().
csrf().
csrfTokenRepository(csrfTokenRepository()).
and().
addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}

private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}

private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}

}





'use strict';
angular
.module('webApp')
.controller('LoginCtrl', ['$root`enter code here`Scope', '$scope', '$http', '$location', '$route', function($rootScope, $scope, $http, $location, $route) {
console.log("LoginCtrl created.");

var vm = this;
vm.credentials = {
username: "",
password: ""
};
//vm.login = login;

$scope.tab = function(route) {
return $route.current && route === $route.current.controller;
};

var authenticate = function(callback) {

$http.get('user').success(function(data) {
console.log("/user success: " + JSON.stringify(data));
if (data.name) {
console.log("And Authenticated!");
$rootScope.authenticated = true;
} else {
console.log("But received invalid data.");
$rootScope.authenticated = false;
}
callback && callback();
}).error(function(response) {
console.log("/user failure." + JSON.stringify(response));
$rootScope.authenticated = false;
callback && callback();
});

};

authenticate();

$scope.login = function() {

var data2 = 'username=' + encodeURIComponent(vm.credentials.username) +
'&password=' + encodeURIComponent(vm.credentials.password);

$http.post('login', data2, {
headers : {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function() {
authenticate(function() {
if ($rootScope.authenticated) {
console.log("Login succeeded");
$location.path("/");
$scope.error = false;
$rootScope.authenticated = true;
} else {
console.log("Login failed with redirect");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
}
});
}).error(function() {
console.log("Login failed");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
})
};

$scope.logout = function() {
$http.post('logout', {}).success(function() {
$rootScope.authenticated = false;
$location.path("/");
}).error(function() {
console.log("Logout failed");
$rootScope.authenticated = false;
});
}

}]);





'use strict';
angular
.module('webApp')
.controller('LoginCtrl', ['$root`enter code here`Scope', '$scope', '$http', '$location', '$route', function($rootScope, $scope, $http, $location, $route) {
console.log("LoginCtrl created.");

var vm = this;
vm.credentials = {
username: "",
password: ""
};
//vm.login = login;

$scope.tab = function(route) {
return $route.current && route === $route.current.controller;
};

var authenticate = function(callback) {

$http.get('user').success(function(data) {
console.log("/user success: " + JSON.stringify(data));
if (data.name) {
console.log("And Authenticated!");
$rootScope.authenticated = true;
} else {
console.log("But received invalid data.");
$rootScope.authenticated = false;
}
callback && callback();
}).error(function(response) {
console.log("/user failure." + JSON.stringify(response));
$rootScope.authenticated = false;
callback && callback();
});

};

authenticate();

$scope.login = function() {

var data2 = 'username=' + encodeURIComponent(vm.credentials.username) +
'&password=' + encodeURIComponent(vm.credentials.password);

$http.post('login', data2, {
headers : {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function() {
authenticate(function() {
if ($rootScope.authenticated) {
console.log("Login succeeded");
$location.path("/");
$scope.error = false;
$rootScope.authenticated = true;
} else {
console.log("Login failed with redirect");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
}
});
}).error(function() {
console.log("Login failed");
$location.path("/login");
$scope.error = true;
$rootScope.authenticated = false;
})
};

$scope.logout = function() {
$http.post('logout', {}).success(function() {
$rootScope.authenticated = false;
$location.path("/");
}).error(function() {
console.log("Logout failed");
$rootScope.authenticated = false;
});
}

}]);






java angularjs spring spring-security spring-boot






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 11 '15 at 17:00









Andrew

1291413




1291413












  • If you get redirected to /login that means you are not authenticated (but it shouldn't be a 404 so that's odd). You can switch on debug logging for org.springframework.security to get more detailed information about the access decision (I expect the credentials were bad in some way), e.g. set logging.level.org.springframework.security=DEBUG in application.[properties,yml].
    – Dave Syer
    Feb 11 '15 at 18:06












  • @DaveSyer Looking through the logs, I can't seem to even see a POST to /login How can I verify that Spring is handling POST /login? pastebin.com/GeUkCUvg
    – Andrew
    Feb 11 '15 at 20:12








  • 1




    It appears to be a path issue (or possibly scope), as I was able to pull your "single" project from the github examples, remove the wro4j, and replace with the following bower dependencies: "angular": "^1.3.0", "angular-resource": "^1.3.0", "angular-bootstrap": "~0.12.0", "bootstrap-css-only": "~3.3.2", "angular-route": "~1.3.11" And using... var req = 'username=' + ($scope.credentials.username) + =' + ($scope.credentials.password); $http.post('login', req.... Seems to work fine
    – Andrew
    Feb 11 '15 at 21:00












  • I also can't see a POST to /login but the log seemed to end in the middle of loading the homepage. Are you sure your client actually sent a POST anyway (can you see that in the client, and what are the request/response headers)?
    – Dave Syer
    Feb 11 '15 at 22:14










  • OK, the 404 is obvious: your client is sending a GET to /login/ which you have declared to be permitAll() but haven't provided a view for. Spring Security provides a whitelabel view at /login (no trailing slash), and it only sends /login in 302 responses, so your client is behaving rather strangely.
    – Dave Syer
    Feb 12 '15 at 10:15


















  • If you get redirected to /login that means you are not authenticated (but it shouldn't be a 404 so that's odd). You can switch on debug logging for org.springframework.security to get more detailed information about the access decision (I expect the credentials were bad in some way), e.g. set logging.level.org.springframework.security=DEBUG in application.[properties,yml].
    – Dave Syer
    Feb 11 '15 at 18:06












  • @DaveSyer Looking through the logs, I can't seem to even see a POST to /login How can I verify that Spring is handling POST /login? pastebin.com/GeUkCUvg
    – Andrew
    Feb 11 '15 at 20:12








  • 1




    It appears to be a path issue (or possibly scope), as I was able to pull your "single" project from the github examples, remove the wro4j, and replace with the following bower dependencies: "angular": "^1.3.0", "angular-resource": "^1.3.0", "angular-bootstrap": "~0.12.0", "bootstrap-css-only": "~3.3.2", "angular-route": "~1.3.11" And using... var req = 'username=' + ($scope.credentials.username) + =' + ($scope.credentials.password); $http.post('login', req.... Seems to work fine
    – Andrew
    Feb 11 '15 at 21:00












  • I also can't see a POST to /login but the log seemed to end in the middle of loading the homepage. Are you sure your client actually sent a POST anyway (can you see that in the client, and what are the request/response headers)?
    – Dave Syer
    Feb 11 '15 at 22:14










  • OK, the 404 is obvious: your client is sending a GET to /login/ which you have declared to be permitAll() but haven't provided a view for. Spring Security provides a whitelabel view at /login (no trailing slash), and it only sends /login in 302 responses, so your client is behaving rather strangely.
    – Dave Syer
    Feb 12 '15 at 10:15
















If you get redirected to /login that means you are not authenticated (but it shouldn't be a 404 so that's odd). You can switch on debug logging for org.springframework.security to get more detailed information about the access decision (I expect the credentials were bad in some way), e.g. set logging.level.org.springframework.security=DEBUG in application.[properties,yml].
– Dave Syer
Feb 11 '15 at 18:06






If you get redirected to /login that means you are not authenticated (but it shouldn't be a 404 so that's odd). You can switch on debug logging for org.springframework.security to get more detailed information about the access decision (I expect the credentials were bad in some way), e.g. set logging.level.org.springframework.security=DEBUG in application.[properties,yml].
– Dave Syer
Feb 11 '15 at 18:06














@DaveSyer Looking through the logs, I can't seem to even see a POST to /login How can I verify that Spring is handling POST /login? pastebin.com/GeUkCUvg
– Andrew
Feb 11 '15 at 20:12






@DaveSyer Looking through the logs, I can't seem to even see a POST to /login How can I verify that Spring is handling POST /login? pastebin.com/GeUkCUvg
– Andrew
Feb 11 '15 at 20:12






1




1




It appears to be a path issue (or possibly scope), as I was able to pull your "single" project from the github examples, remove the wro4j, and replace with the following bower dependencies: "angular": "^1.3.0", "angular-resource": "^1.3.0", "angular-bootstrap": "~0.12.0", "bootstrap-css-only": "~3.3.2", "angular-route": "~1.3.11" And using... var req = 'username=' + ($scope.credentials.username) + =' + ($scope.credentials.password); $http.post('login', req.... Seems to work fine
– Andrew
Feb 11 '15 at 21:00






It appears to be a path issue (or possibly scope), as I was able to pull your "single" project from the github examples, remove the wro4j, and replace with the following bower dependencies: "angular": "^1.3.0", "angular-resource": "^1.3.0", "angular-bootstrap": "~0.12.0", "bootstrap-css-only": "~3.3.2", "angular-route": "~1.3.11" And using... var req = 'username=' + ($scope.credentials.username) + =' + ($scope.credentials.password); $http.post('login', req.... Seems to work fine
– Andrew
Feb 11 '15 at 21:00














I also can't see a POST to /login but the log seemed to end in the middle of loading the homepage. Are you sure your client actually sent a POST anyway (can you see that in the client, and what are the request/response headers)?
– Dave Syer
Feb 11 '15 at 22:14




I also can't see a POST to /login but the log seemed to end in the middle of loading the homepage. Are you sure your client actually sent a POST anyway (can you see that in the client, and what are the request/response headers)?
– Dave Syer
Feb 11 '15 at 22:14












OK, the 404 is obvious: your client is sending a GET to /login/ which you have declared to be permitAll() but haven't provided a view for. Spring Security provides a whitelabel view at /login (no trailing slash), and it only sends /login in 302 responses, so your client is behaving rather strangely.
– Dave Syer
Feb 12 '15 at 10:15




OK, the 404 is obvious: your client is sending a GET to /login/ which you have declared to be permitAll() but haven't provided a view for. Spring Security provides a whitelabel view at /login (no trailing slash), and it only sends /login in 302 responses, so your client is behaving rather strangely.
– Dave Syer
Feb 12 '15 at 10:15












2 Answers
2






active

oldest

votes

















up vote
0
down vote













Try adding WebSecuritConfigAdapter



@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers("/**").permitAll()
.anyRequest().authenticated();
}
}





share|improve this answer




























    up vote
    0
    down vote













    There is one thing worng with login.js that it invokes authenticate() which calls /user and you get a redirect to GET /login/. Spring looks for login.jsp which is not there and end up with 404 Not Found.



    You can make it work by taking following steps:



    1) Remove invocation of authenticate() from line 38 in login.js



    2) Add login processing URL like:



    http.
    formLogin().
    loginProcessingUrl("/perform_login").
    and().
    logout()
    ....


    3) Change your login URL to 'perform_login' like:



    $http.post('perform_login', data2, {
    headers : {
    'Content-Type': 'application/x-www-form-urlencoded'
    }
    })....


    and it works, you get the user.



    Refer to http://www.baeldung.com/spring-security-login for spring security config.






    share|improve this answer




















      protected by Community Aug 25 '16 at 15:36



      Thank you for your interest in this question.
      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



      Would you like to answer one of these unanswered questions instead?














      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      0
      down vote













      Try adding WebSecuritConfigAdapter



      @Configuration
      @EnableWebSecurity
      @EnableGlobalMethodSecurity
      public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

      @Override
      protected void configure(HttpSecurity httpSecurity) throws Exception {
      httpSecurity
      .authorizeRequests()
      .antMatchers("/**").permitAll()
      .anyRequest().authenticated();
      }
      }





      share|improve this answer

























        up vote
        0
        down vote













        Try adding WebSecuritConfigAdapter



        @Configuration
        @EnableWebSecurity
        @EnableGlobalMethodSecurity
        public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
        .authorizeRequests()
        .antMatchers("/**").permitAll()
        .anyRequest().authenticated();
        }
        }





        share|improve this answer























          up vote
          0
          down vote










          up vote
          0
          down vote









          Try adding WebSecuritConfigAdapter



          @Configuration
          @EnableWebSecurity
          @EnableGlobalMethodSecurity
          public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

          @Override
          protected void configure(HttpSecurity httpSecurity) throws Exception {
          httpSecurity
          .authorizeRequests()
          .antMatchers("/**").permitAll()
          .anyRequest().authenticated();
          }
          }





          share|improve this answer












          Try adding WebSecuritConfigAdapter



          @Configuration
          @EnableWebSecurity
          @EnableGlobalMethodSecurity
          public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

          @Override
          protected void configure(HttpSecurity httpSecurity) throws Exception {
          httpSecurity
          .authorizeRequests()
          .antMatchers("/**").permitAll()
          .anyRequest().authenticated();
          }
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 27 '17 at 18:31









          hya

          1,2251018




          1,2251018
























              up vote
              0
              down vote













              There is one thing worng with login.js that it invokes authenticate() which calls /user and you get a redirect to GET /login/. Spring looks for login.jsp which is not there and end up with 404 Not Found.



              You can make it work by taking following steps:



              1) Remove invocation of authenticate() from line 38 in login.js



              2) Add login processing URL like:



              http.
              formLogin().
              loginProcessingUrl("/perform_login").
              and().
              logout()
              ....


              3) Change your login URL to 'perform_login' like:



              $http.post('perform_login', data2, {
              headers : {
              'Content-Type': 'application/x-www-form-urlencoded'
              }
              })....


              and it works, you get the user.



              Refer to http://www.baeldung.com/spring-security-login for spring security config.






              share|improve this answer

























                up vote
                0
                down vote













                There is one thing worng with login.js that it invokes authenticate() which calls /user and you get a redirect to GET /login/. Spring looks for login.jsp which is not there and end up with 404 Not Found.



                You can make it work by taking following steps:



                1) Remove invocation of authenticate() from line 38 in login.js



                2) Add login processing URL like:



                http.
                formLogin().
                loginProcessingUrl("/perform_login").
                and().
                logout()
                ....


                3) Change your login URL to 'perform_login' like:



                $http.post('perform_login', data2, {
                headers : {
                'Content-Type': 'application/x-www-form-urlencoded'
                }
                })....


                and it works, you get the user.



                Refer to http://www.baeldung.com/spring-security-login for spring security config.






                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  There is one thing worng with login.js that it invokes authenticate() which calls /user and you get a redirect to GET /login/. Spring looks for login.jsp which is not there and end up with 404 Not Found.



                  You can make it work by taking following steps:



                  1) Remove invocation of authenticate() from line 38 in login.js



                  2) Add login processing URL like:



                  http.
                  formLogin().
                  loginProcessingUrl("/perform_login").
                  and().
                  logout()
                  ....


                  3) Change your login URL to 'perform_login' like:



                  $http.post('perform_login', data2, {
                  headers : {
                  'Content-Type': 'application/x-www-form-urlencoded'
                  }
                  })....


                  and it works, you get the user.



                  Refer to http://www.baeldung.com/spring-security-login for spring security config.






                  share|improve this answer












                  There is one thing worng with login.js that it invokes authenticate() which calls /user and you get a redirect to GET /login/. Spring looks for login.jsp which is not there and end up with 404 Not Found.



                  You can make it work by taking following steps:



                  1) Remove invocation of authenticate() from line 38 in login.js



                  2) Add login processing URL like:



                  http.
                  formLogin().
                  loginProcessingUrl("/perform_login").
                  and().
                  logout()
                  ....


                  3) Change your login URL to 'perform_login' like:



                  $http.post('perform_login', data2, {
                  headers : {
                  'Content-Type': 'application/x-www-form-urlencoded'
                  }
                  })....


                  and it works, you get the user.



                  Refer to http://www.baeldung.com/spring-security-login for spring security config.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 8 at 21:37









                  Zohaib Jawaid

                  985




                  985

















                      protected by Community Aug 25 '16 at 15:36



                      Thank you for your interest in this question.
                      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                      Would you like to answer one of these unanswered questions instead?



                      Popular posts from this blog

                      Xamarin.iOS Cant Deploy on Iphone

                      Glorious Revolution

                      Dulmage-Mendelsohn matrix decomposition in Python