I am implementing a Login page with AngularJS to authenticate against LDAP server. The authentication at the back end is done by Spring Security. Basically username and password are sent to server via a post request which is handled by Spring without an explicit handler.
When I submit the login form, the post request returns 302 and redirect to another url based on whether credentials are valid or not. If the password is correct, it will initiate GET request to "http://localhost:8080/". If password is wrong, it redirects to "http://localhost:8080/login?error". This is known behavior of Spring Security. According to Dave Syer's article, "the Spring Security default behaviour is to send a 302 on success and failure, and Angular will follow the redirect, so we would have to actually parse the response from that". In Dave's tutorial, he used a helper function to verify the authentication in the general case. I don't think it would work for LDAP authentication though.
I found another very similar post Spring Boot and Security with custom AngularJS Login page. Although it does not have an official answer, based on the last comment, it seems modifying paths in .antMatchers in Java config may have resolved the issue. However I played with my security config (see below) back and forth and it did not seem to help.
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class)
.csrf().disable()
.authorizeRequests()
.antMatchers("/login/", "/login","login/")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin();
}
Although 302 does not produce any response, client somehow knows which url to redirect to based on credential's validity. My understanding is that the server must have told client if authentication succeeds or not in a "secret" way. If I capture and parse this hidden information before client sends GET request, I could make the authentication work with Angular. Something like this (partially pseudo code):
app.controller("LoginCtrl", ['$scope', '$location',
function($scope, $location){
$scope.authenticate = function() {
loginFactory.login($scope.username, $scope.password) {
// pseudo code starts
if (redirect.path == 'localhost') {
$location.path('/main');
}
else {
$location.path('/loginfail');
console.log("Login failed");
}
}
}]);
The question is how to diagnose the 302 and identify the nature of the response before redirect happens? Worst case scenario, I could let the redirect to start, and grab response.path from the GET request and decide whether login is successful. But I try not to go down that path. Need suggestion badly.